Khi nào thì tốt hơn để sử dụng zipthay vì itertools.izip?
zipchức năng của Python 3 là của Python 2 izip. Nói chung, Python 3 đã thay đổi hầu hết các chức năng để sử dụng các trình vòng lặp, như phạm vi, bộ lọc, các hàm dict, v.v.
Khi nào thì tốt hơn để sử dụng zipthay vì itertools.izip?
zipchức năng của Python 3 là của Python 2 izip. Nói chung, Python 3 đã thay đổi hầu hết các chức năng để sử dụng các trình vòng lặp, như phạm vi, bộ lọc, các hàm dict, v.v.
Câu trả lời:
Khi bạn biết rằng bạn sẽ muốn danh sách đầy đủ các mục được tạo (ví dụ: để chuyển đến một hàm có thể sửa đổi danh sách đó tại chỗ). Hoặc khi bạn muốn buộc các đối số bạn đang chuyển zip()đến được đánh giá hoàn toàn tại điểm cụ thể đó.
izipchỉ sử dụng lại tupleif tupleđã được phát hành trước khi lần lặp tiếp theo bắt đầu, vì vậy nó không giúp bạn được gì. Điều đó nói rằng, bất kỳ tổn thất nào cũng là nhỏ, vì vậy tôi đồng ý rằng có rất ít lý do để không sử dụng izipđộc quyền, gói với listnếu bạn cần list; bạn thực sự có thể làm điều này một cách "đúng đắn" bằng cách thêm from future_builtins import zipmã Py2, mà làm cho đồng bằng zipvào izip(chuẩn bị cho quá trình chuyển đổi Py3).
ziptính toán tất cả danh sách cùng một lúc, chỉ iziptính toán các phần tử khi được yêu cầu.
Một điểm khác biệt quan trọng là 'zip' trả về danh sách thực, 'izip' trả về 'đối tượng izip', không phải là danh sách và không hỗ trợ các tính năng dành riêng cho danh sách (chẳng hạn như lập chỉ mục):
>>> l1 = [1, 2, 3, 4, 5, 6]
>>> l2 = [2, 3, 4, 5, 6, 7]
>>> z = zip(l1, l2)
>>> iz = izip(l1, l2)
>>> isinstance(zip(l1, l2), list)
True
>>> isinstance(izip(l1, l2), list)
False
>>> z[::2] #Get odd places
[(1, 2), (3, 4), (5, 6)]
>>> iz[::2] #Same with izip
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'itertools.izip' object is unsubscriptable
Vì vậy, nếu bạn cần một danh sách (một đối tượng không giống như danh sách), chỉ cần sử dụng 'zip'.
Ngoài ra, 'izip' có thể hữu ích để tiết kiệm bộ nhớ hoặc chu kỳ.
Ví dụ: đoạn mã sau có thể thoát sau một vài chu kỳ, vì vậy không cần tính toán tất cả các mục của danh sách kết hợp:
lst_a = ... #list with very large number of items
lst_b = ... #list with very large number of items
#At each cycle, the next couple is provided
for a, b in izip(lst_a, lst_b):
if a == b:
break
print a
sử dụng zipsẽ tính toán tất cả các (a, b) cặp trước khi bước vào chu kỳ.
Hơn nữa, nếu lst_avà lst_brất lớn (ví dụ hàng triệu bản ghi), zip(a, b)sẽ xây dựng một danh sách thứ ba với không gian gấp đôi.
Nhưng nếu bạn có danh sách nhỏ, có thể zipnhanh hơn.
Trong 2.x, khi bạn cần một danh sách thay vì một trình lặp.
itertools.izip()ngoại trừ trường hợp lợi nhuận thu được hoàn toàn là thống kê.
lst = zip(lst_a, lst_b)cho phép lst[1]hoặc len(lst). Tuy nhiên, ilst = itertools.izip(lst_a, lst_n)bạn sẽ thất bại khi cố gắng ilst[1]hoặc len(ilst).
Thư viện itertools cung cấp "trình vòng lặp" cho các hàm Python phổ biến. Từ tài liệu itertools, "Giống như zip () ngoại trừ việc nó trả về một trình lặp thay vì danh sách." I trong izip () có nghĩa là "trình lặp".
Các trình vòng lặp Python là một chuỗi "được tải chậm" giúp tiết kiệm bộ nhớ qua danh sách trong bộ nhớ thông thường. Vì vậy, bạn sẽ sử dụng itertools.izip (a, b) khi hai đầu vào a, b quá lớn để lưu trong bộ nhớ cùng một lúc.
Tra cứu các khái niệm Python liên quan đến xử lý tuần tự hiệu quả:
"generators" & "yield"
"iterators"
"lazy loading"
zip, quá rõ ràng nhưng vẫn đáng được chỉ ra, làiziptrả về mộtiteratorchỉ có thể được duyệt một lần. tức là ởii = izip(a,b) ; f(ii) ; g(ii)đây một danh sách trống[]được chuyển đếng.