Khi nào thì tốt hơn nên sử dụng zip thay vì izip?


81

Khi nào thì tốt hơn để sử dụng zipthay vì itertools.izip?


Một lý do ủng hộ zip, quá rõ ràng nhưng vẫn đáng được chỉ ra, là iziptrả về một iteratorchỉ 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 đến g.
Nhân quả

5
FYI, 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.
Charles L.

Câu trả lời:


44

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ể đó.


1
Sẽ không tốt hơn nếu sử dụng izip trong trường hợp đầu tiên vì nó nhanh hơn vì nó sử dụng lại bộ tuple và không có lý do thực sự nào để không sử dụng izip?
user1815201

1
@ user1815201: 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).
ShadowRanger

98

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_alst_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.


9
Bạn đúng. Tôi bắt đầu với những ý định tốt và sau đó rơi vào những thứ lý thuyết ...
Don

5

Trong 2.x, khi bạn cần một danh sách thay vì một trình lặp.


Bạn có thể cho tôi một ví dụ mà điều đó có thể xảy ra không?
Neil G

3
Không hẳn vậy. Đó là lý do tại sao tôi có xu hướng thích itertools.izip()ngoại trừ trường hợp lợi nhuận thu được hoàn toàn là thống kê.
Ignacio Vazquez-Abrams

2
Một trường hợp, khi bạn cần danh sách, là khi bạn định truy cập các mục của kết quả theo chỉ mục hoặc cần tìm tổng độ dài. 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).
Jan Vlcinsky

5

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"

Giải thích độc đáo.
Rahul
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.