標籤:

Python版本3.3有zip這個用法嗎?

按理來說,這個code是沒錯的,會return出[(0,3),(1,1),(2,4)]的結果,但是最後一行那是什麼?誰能解釋一下?


回答:當然是有的!下面具體分析不同:

  1. zip方法在Python 2 和Python 3中的不同
  2. 為何有這種不同
  3. 更多註解

問題一:zip方法在Python 2 和Python 3中的不同

Python 2 的代碼演示:

$ python2
&>&>&> a = zip((1, 2), (3, 4))
&>&>&> a
[(1, 3), (2, 4)]
# 可以看到這裡返回的是一個list

Python 3 的代碼演示:

$ python3
&>&>&> a = zip((1, 2), (3, 4))
&>&>&> a
&
# 可以看到這裡返回的是一個對象,這裡就是2和3的不同點
&>&>&> dir(a) # 查看a的相關屬性
[__class__, __delattr__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __gt__, __hash__, __init__, __iter__, __le__, __lt__, __ne__, __new__, __next__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__]
# 這裡值得注意的是__next__方法,說明a是一個迭代器
# 既然知道了a是一個迭代器,我們也就基本明白了a的用法了
### 和Python2的區別(一):返回的是一個迭代器,而不是一個list本身
&>&>&> for i in a: print(i) # in 方法
...
(1, 3)
(2, 4)
&>&>&> next(a) # 我們測試__next__方法
Traceback (most recent call last):
File "&", line 1, in &
StopIteration # 說明next方法是支持的
&>&>&> a = zip((1, 2), (3, 4)) # 這裡需要重新賦值,迭代器只能遍歷一次
&>&>&> next(a)
(1, 3) # 運行良好
### 返回迭代器

問題二:為何有這種不同

我想最重要的原因是節約了不少的內存吧。Python的運行效率和編譯類型的語言自然是沒法比,但是能優化就優化一點吧~誰不想有更高的追求呢。

問題三:更多註解

這個zip在不同版本的不同反應了python的一個演變:大部分返回list的函數不在返回list,而是返回一個支持遍歷的對象,比如map、fiter之類的,基本的例子如下:

$ python3
&>&>&> a = map(abs, [1, 2, -3])
&>&>&> a
&

&>&>&> list(a) # 如果不習慣,可以自己手動轉化為list,也是寫兼容代碼需要注意的地方
[1, 2, 3]
$ python2
&>&>&> a = map(abs, [1, 2, -3])
&>&>&> a
[1, 2, 3]

註:《Learning Python》by Mark Lutz,第五版很不錯,值得推薦。


最後一行不就是zip(*list)的返回么?


我用專欄里的一篇文章來答題。

專欄鏈接:給妹子講python,歡迎大家關注,提意見!

說實話,python這麼好用,就是因為有很多像zip這樣的函數。下面我來詳細說說。

zip:並行迭代多個序列

內置zip函數允許我們使用for循環來並行迭代多個序列。zip使用多個序列作為參數,然後返回元組的列表,將這些序列中的並排元素一一配對。

L1 = [1,2,3,4,5]
L2 = [A,B,C,D,E]
for t in zip(L1,L2):
print(t, end=,)

(1, A),(2, B),(3, C),(4, D),(5, E),

和range一樣,zip在遍歷時也是依次按需產生結果,而不是一次性顯示所有結果

L1 = [1,2,3,4,5]
L2 = [A,B,C,D,E]

print(zip(L1,L2))
&

同樣的,如果想一次性顯示所有結果,則必須將其包含在一個list調用中,以便一次性顯示所有結果

L1 = [1,2,3,4,5]
L2 = [A,B,C,D,E]
print(list(zip(L1,L2)))

[(1, A), (2, B), (3, C), (4, D), (5, E)]

最後只說明一點,當zip的多個參數長度不同時,zip會以最短序列的長度為準來截斷所得到的元組

L1 = [1,2,3,4,5]
L2 = [A,B,C]
print(list(zip(L1,L2)))

[(1, A), (2, B), (3, C)]

回顧一下,之前我們談到過,當字典的鍵和值必須在運行時計算產生時,zip函數可以用於產生這樣的字典

keys = [A, B, C]

vals = [1, 2, 3]

D = dict(zip(keys,vals))

print(D)

{C: 3, A: 1, B: 2}

@color @勞里林 @周星辰


樓上看來是沒理解題主的問題了,zip(*list)是指解壓操作,返回多個tuple


推薦閱讀:

我的Live -- 爬蟲從入門到進階
python寫的CGI腳本,用print為什麼不是列印到控制台,而是發送到客戶端?
喵哥的Django學習筆記1:安裝
寫爬蟲不會正則表達式?看這篇文章試試
PY交易(一)使用Pygame

TAG:Python |