Câu hỏi Python - write () so với writelines () và các chuỗi được nối


Vì vậy, tôi đang học Python. Tôi đang trải qua các bài học và gặp phải một vấn đề mà tôi phải ngưng tụ rất nhiều target.write() thành một đĩa đơn write(), trong khi có một "\n" giữa mỗi biến đầu vào của người dùng (đối tượng của write()).

Tôi đến với:

nl = "\n"
lines = line1, nl, line2, nl, line3, nl
textdoc.writelines(lines)

Nếu tôi cố gắng làm:

textdoc.write(lines)

Tôi gặp lỗi. Nhưng nếu tôi gõ:

textdoc.write(line1 + "\n" + line2 + ....)

Sau đó, nó hoạt động tốt. Tại sao tôi không thể sử dụng chuỗi cho một dòng mới trong write() nhưng tôi có thể sử dụng nó trong writelines()?

Python 2,7 Khi tôi tìm kiếm trên google hầu hết các tài nguyên tôi tìm thấy là cách trên đầu của tôi, tôi vẫn là một người dân.


76
2017-09-11 20:31


gốc




Các câu trả lời:


writelines mong đợi một danh sách các chuỗi, trong khi write mong đợi một chuỗi đơn.

line1 + "\n" + line2 hợp nhất các chuỗi đó lại với nhau thành một chuỗi duy nhất trước khi chuyển đến write.

Lưu ý rằng nếu bạn có nhiều dòng, bạn có thể muốn sử dụng "\n".join(list_of_lines).


93
2017-09-11 20:36



Cụ thể hơn, writelines mong đợi một iterable. Bạn có thể sử dụng danh sách, bộ tuple hoặc máy phát. - Mark Ransom
Cảm ơn bạn vì câu trả lời thưa sếp. Tôi giả định bởi tên (list_of_lines) mà tôi nên làm cho một danh sách các chuỗi và vượt qua sau đó vào .join (danh sách)? - AbeLinkon
@AbeLinkon: Bạn được chào đón, và đó là chính xác. - DGH
Tại sao bạn nên sử dụng write thay vì writelines nếu bạn có nhiều dòng? Writelines có thể hoạt động tốt hơn vì nó không phải tạo một chuỗi ghép nối tạm thời, chỉ cần lặp qua các dòng. - bouke
@MarkRansom. Tôi nghĩ bạn có ý nghĩa hơn nói chung :) - Mad Physicist


Tại sao tôi không thể sử dụng một chuỗi cho một dòng mới trong write () nhưng tôi có thể sử dụng nó trong writelines ()?

Ý tưởng là như sau: nếu bạn muốn viết một chuỗi, bạn có thể làm điều này với write(). Nếu bạn có một chuỗi các chuỗi, bạn có thể viết tất cả bằng cách sử dụng writelines().

write(arg) mong đợi một chuỗi làm đối số và ghi nó vào tệp. Nếu bạn cung cấp một danh sách các chuỗi, nó sẽ tăng một ngoại lệ (bằng cách này, hiển thị lỗi cho chúng tôi!).

writelines(arg) mong đợi một đối số có thể lặp lại (một đối tượng có thể lặp lại có thể là một bộ tuple, một danh sách, một chuỗi hoặc một trình lặp trong ý nghĩa chung nhất). Mỗi mục chứa trong trình lặp được dự kiến ​​là một chuỗi. Một chuỗi các chuỗi là những gì bạn cung cấp, vì vậy mọi thứ hoạt động.

Bản chất của (các) chuỗi không quan trọng đối với cả hai hàm, nghĩa là chúng chỉ ghi vào tệp bất kỳ điều gì bạn cung cấp. Phần thú vị là writelines() không tự thêm các ký tự dòng mới, do đó tên phương thức thực sự có thể khá khó hiểu. Nó thực sự hoạt động như một phương pháp tưởng tượng được gọi là write_all_of_these_strings(sequence).

Những gì sau là một cách thành ngữ trong Python để viết một danh sách các chuỗi vào một tập tin trong khi vẫn giữ mỗi chuỗi trong dòng riêng của nó:

lines = ['line1', 'line2']
with open('filename.txt', 'w') as f:
    f.write('\n'.join(lines))

Điều này sẽ giúp bạn đóng tập tin. Xay dung '\n'.join(lines) concatenates (kết nối) các chuỗi trong danh sách lines và sử dụng ký tự '\ n' làm keo. Nó hiệu quả hơn việc sử dụng + nhà điều hành.

Bắt đầu từ cùng một lines trình tự, kết thúc với cùng một đầu ra, nhưng sử dụng writelines():

lines = ['line1', 'line2']
with open('filename.txt', 'w') as f:
    f.writelines("%s\n" % l for l in lines)

Điều này làm cho việc sử dụng một biểu thức máy phát và tự động tạo ra các chuỗi được kết thúc bằng dòng mới. writelines() lặp lại chuỗi chuỗi này và viết mọi mục.

Chỉnh sửa: Một điểm khác bạn nên biết:

write() và readlines() tồn tại trước writelines() đã được giới thiệu. writelines() được giới thiệu sau này với tư cách là một đối tác readlines(), để người ta có thể dễ dàng viết nội dung tập tin vừa đọc qua readlines():

outfile.writelines(infile.readlines())

Thực sự, đây là lý do chính tại sao writelines có một cái tên khó hiểu. Ngoài ra, hôm nay, chúng tôi không thực sự muốn sử dụng phương pháp này nữa. readlines() đọc toàn bộ tập tin vào bộ nhớ của máy trước writelines() bắt đầu ghi dữ liệu. Trước hết, điều này có thể lãng phí thời gian. Tại sao không bắt đầu viết các phần dữ liệu trong khi đọc các phần khác? Nhưng, quan trọng nhất, cách tiếp cận này có thể tốn rất nhiều bộ nhớ. Trong một kịch bản cực đoan, nơi tệp đầu vào lớn hơn bộ nhớ của máy tính của bạn, cách tiếp cận này thậm chí sẽ không hoạt động. Giải pháp cho vấn đề này là sử dụng các trình vòng lặp. Một ví dụ làm việc:

with open('inputfile') as infile:
    with open('outputfile') as outfile:
        for line in infile:
            outfile.write(line)

Điều này đọc dòng tập tin đầu vào theo dòng. Ngay sau khi một dòng được đọc, dòng này được ghi vào tệp đầu ra. Nói một cách sơ bộ, luôn luôn có một dòng duy nhất trong bộ nhớ (so với toàn bộ nội dung tập tin nằm trong bộ nhớ trong trường hợp của phương pháp readlines / writelines).


90
2017-09-11 20:40



@AbeLinkon: Tôi sẽ không ủng hộ kết luận này. write() và writelines() về cơ bản là tương đương và cách sử dụng của chúng cũng là một câu hỏi về sở thích cá nhân. Tuy nhiên, điều quan trọng cần lưu ý là đối với một danh sách rất dài các chuỗi (được gọi là lines) viết ít hiệu quả hơn f.write('\n'.join(lines)) hơn for l in line: f.write('%s\n' % l). Trong trường hợp đầu tiên, một chuỗi hoàn toàn mới và rất dài được tạo ra trong bộ nhớ trước khi viết nó. Trong trường hợp thứ hai, dữ liệu được viết một cách khôn ngoan. - Jan-Philip Gehrcke
f.write ('\ n'.join (dòng)) không thêm nl cuối cùng khi tôi chạy nó. - Jiminion
Tất nhiên bạn sẽ không làm outf.writelines(inf.readlines()) mà đúng hơn là outf.writelines(inf). Hàm chúng tôi không muốn sử dụng nữa là readlines() không phải writelines(). - moooeeeep
@moooeeeep: trong khi không có gì sai với chức năng / triển khai writelines(), ngữ nghĩa của nó, như được giải thích, ít hơn lý tưởng. Đây là lý do tại sao tôi chưa bao giờ sử dụng nó. Và tôi không bao giờ bỏ lỡ nó. - Jan-Philip Gehrcke
@AbeLinkon - có thể bạn nên cân nhắc chấp nhận câu trả lời này, rõ ràng là tốt hơn câu trả lời bạn đã chấp nhận ban đầu - P.M


Trên thực tế, tôi nghĩ rằng vấn đề là biến "dòng" của bạn là xấu. Bạn đã định nghĩa các dòng như một bộ tuple, nhưng tôi tin rằng write () yêu cầu một chuỗi. Tất cả những gì bạn phải thay đổi là dấu phẩy của bạn thành dấu cộng (+).

nl = "\n"
lines = line1+nl+line2+nl+line3+nl
textdoc.writelines(lines)

nên làm việc.


-2
2017-09-17 22:18



Yikes. Ơn Chúa .join() tồn tại. - ZAD-Man


nếu bạn chỉ muốn lưu và tải danh sách thử Pickle

Tiết kiệm dưa:

with open("yourFile","wb")as file:
 pickle.dump(YourList,file)

và tải:

with open("yourFile","rb")as file:
 YourList=pickle.load(file)

-2
2018-03-11 15:29





Bài tập 16 từ cuốn sách của Zed Shaw? Bạn có thể sử dụng các ký tự thoát như sau:

paragraph1 = "%s \n %s \n %s \n" % (line1, line2, line3)
target.write(paragraph1)
target.close()

-2
2018-02-06 07:30