Khi nào thì tốt hơn để sử dụng zip
thay vì itertools.izip
?
zip
chứ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 zip
thay vì itertools.izip
?
zip
chứ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ể đó.
izip
chỉ sử dụng lại tuple
if 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 list
nế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 zip
mã Py2, mà làm cho đồng bằng zip
vào izip
(chuẩn bị cho quá trình chuyển đổi Py3).
zip
tính toán tất cả danh sách cùng một lúc, chỉ izip
tí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 zip
sẽ 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_a
và lst_b
rấ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ể zip
nhanh 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àizip
trả về mộtiterator
chỉ 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
.