Điểm quan trọng là việc hiểu danh sách tạo ra một danh sách mới. Trình tạo tạo một đối tượng có thể lặp lại sẽ "lọc" vật liệu nguồn đang hoạt động khi bạn tiêu thụ các bit.
Hãy tưởng tượng bạn có một tệp nhật ký 2TB có tên là "hugefile.txt" và bạn muốn nội dung và độ dài cho tất cả các dòng bắt đầu bằng từ "ENTRY".
Vì vậy, bạn hãy thử bắt đầu bằng cách viết một danh sách hiểu:
logfile = open("hugefile.txt","r")
entry_lines = [(line,len(line)) for line in logfile if line.startswith("ENTRY")]
Điều này làm mờ toàn bộ tệp, xử lý từng dòng và lưu trữ các dòng khớp trong mảng của bạn. Do đó, mảng này có thể chứa tới 2TB nội dung. Đó là rất nhiều RAM, và có lẽ không thực tế cho mục đích của bạn.
Vì vậy, thay vào đó chúng ta có thể sử dụng trình tạo để áp dụng "bộ lọc" cho nội dung của mình. Không có dữ liệu thực sự được đọc cho đến khi chúng tôi bắt đầu lặp lại kết quả.
logfile = open("hugefile.txt","r")
entry_lines = ((line,len(line)) for line in logfile if line.startswith("ENTRY"))
Thậm chí không có một dòng nào được đọc từ tệp của chúng tôi. Trong thực tế, giả sử chúng tôi muốn lọc kết quả của chúng tôi hơn nữa:
long_entries = ((line,length) for (line,length) in entry_lines if length > 80)
Vẫn chưa có gì được đọc, nhưng chúng tôi đã chỉ định hai trình tạo sẽ hoạt động trên dữ liệu của chúng tôi như chúng tôi muốn.
Hãy viết ra các dòng được lọc của chúng tôi vào một tệp khác:
outfile = open("filtered.txt","a")
for entry,length in long_entries:
outfile.write(entry)
Bây giờ chúng tôi đọc các tập tin đầu vào. Khi for
vòng lặp của chúng tôi tiếp tục yêu cầu các dòng bổ sung, trình long_entries
tạo yêu cầu các dòng từ trình entry_lines
tạo, chỉ trả về những dòng có độ dài lớn hơn 80 ký tự. Và lần lượt, trình entry_lines
tạo yêu cầu các dòng (được lọc như được chỉ định) từ logfile
iterator, lần lượt đọc tệp.
Vì vậy, thay vì "đẩy" dữ liệu đến chức năng đầu ra của bạn dưới dạng danh sách được điền đầy đủ, bạn sẽ cung cấp cho chức năng đầu ra một cách để "kéo" dữ liệu khi cần. Đây là trường hợp của chúng tôi hiệu quả hơn nhiều, nhưng không hoàn toàn linh hoạt. Máy phát điện là một chiều, một lượt; dữ liệu từ tệp nhật ký chúng tôi đã đọc sẽ bị loại bỏ ngay lập tức, vì vậy chúng tôi không thể quay lại dòng trước đó. Mặt khác, chúng tôi không phải lo lắng về việc giữ dữ liệu xung quanh một khi chúng tôi đã hoàn thành việc đó.
[exp for x in iter]
chỉ có thể là đường cholist((exp for x in iter))
? hoặc có một sự khác biệt thực hiện?