2017-02-16 184 views
1

我想了解爲什麼在Python 3中對zip對象使用排序函數不能多做一次。它只是第二次返回空列表。蟒蛇重複排序3

In [34]: X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"] 
    ...: Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1] 
    ...: yx = zip(Y, X) 
    ...: yx 
    ...: [(0, 'a'), (1, 'b'), (1, 'c'), (0, 'd'), (1, 'e'), (2, 'f'), (2, 'g'), 
    ...: (0, 'h'), (1, 'i')] 
    ...: yx_sorted=sorted(yx) 
    ...: 

In [35]: yx_sorted 
Out[35]: 
[(0, 'a'), 
(0, 'd'), 
(0, 'h'), 
(1, 'b'), 
(1, 'c'), 
(1, 'e'), 
(1, 'i'), 
(2, 'f'), 
(2, 'g')] 

In [36]: yx_sorted=sorted(yx) 

In [37]: yx_sorted 
Out[37]: [] 

In [38]: yx 
Out[38]: <zip at 0x10476aa88> 

yx仍然存在,據我所知。

回答

1

在CPython 3中,zip是一個類,這意味着它是可調用的,這意味着它是該術語廣泛的數學意義上的函數。它記錄在Library ManualBuilt-in Functions章節中。

當被調用時,CPython的zip返回一個zip object,這是一個迭代器,如文檔條目所述(「返回迭代器」)。它有一個__iter__方法,返回self__next__方法具有適當的行爲。由於zip對象是一個迭代器,因此在sorted執行第一次完整迭代後會耗盡。

doc entry中,大致等價的Python代碼用於生成器函數,該函數在調用時返回生成器。 (由於CPython的內置函數使用C編碼,而生成器函數只能用Python編碼,所以CPython將它作爲一個類來實現。)這就是爲什麼人們有些錯誤地說zip會返回一個生成器。但是,由於等效代碼生成的生成器只能用作迭代器,所以效果會相同,並且「返回迭代器」仍然是正確的。如果任何實現(CPython除外)使用Python代碼(PyPy?),那麼對於該實現,zip將是一個生成器。

編輯:添加文檔鏈接項,如下:

由於在問題X和Y是reiterable,zip(X, Y)可以重複得到一個新的,新鮮的迭代與對相同的序列。 sorted(zip(X,Y))多次工作。

+0

@StefanPochmann同意並完成。 –

+0

感謝您的支持!現在向初學者解釋這個問題。 :d –

5

zip是Python 3中的一個生成器。一旦你迭代了一次,它已經耗盡。

+0

我不認爲它是(或返回)一個生成器... –

+0

'zip'是一個函數,但它在Python 3中返回一個生成器。在Python 2中它返回一個列表。 – Bendik

+0

@Bendik我認爲這也不是一個功能。我仍然不認爲它會返回一個發電機。它是一種類型,它返回一個迭代器,我認爲這和應該說/可以說的差不多。 –

0

我使用2.7.13

>>> X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"] 
>>> Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1] 
>>> yx = zip(X, Y) 
>>> yx 
[('a', 0), ('b', 1), ('c', 1), ('d', 0), ('e', 1), ('f', 2), ('g', 2), ('h', 0), ('i', 1)] 
>>> yx_sorted = sorted(yx) 
>>> yx_sorted 
[('a', 0), ('b', 1), ('c', 1), ('d', 0), ('e', 1), ('f', 2), ('g', 2), ('h', 0), ('i', 1)] 
>>> yx 
[('a', 0), ('b', 1), ('c', 1), ('d', 0), ('e', 1), ('f', 2), ('g', 2), ('h', 0), ('i', 1)] 
>>> yx_sorted = sorted(yx) 
>>> yx_sorted 
[('a', 0), ('b', 1), ('c', 1), ('d', 0), ('e', 1), ('f', 2), ('g', 2), ('h', 0), ('i', 1)] 
>>> yx 
[('a', 0), ('b', 1), ('c', 1), ('d', 0), ('e', 1), ('f', 2), ('g', 2), ('h', 0), ('i', 1)] 
>>> 

您使用的是筆記本Jupyter我無法在shell複製呢?也許這與此有關,而不是Python本身?

+1

zip在python 3中給出了一個生成器,在python 2中給出了一個列表。 – Bendik

+0

你是對的。當在Python3中運行時,yx給了我一個'zip對象'。 OP如何讓它返回壓縮列表? –