2016-07-14 88 views
1

一旦一個zip元素已經建成,比方說從兩個列表,跟蹤該ID所構建的拉鍊

z = zip(l1, l2) 

有從z拿到構建l1l2清單ID的方法,或者是z完全不知道它的起源?

我沒有找到,似乎有關的任何方法,但也許......

+3

什麼是你想用這個信息來解決實際問題? – jonrsharpe

+1

有沒有辦法擺脫'z'這些ID(其實,有沒有保證'l1'和'l2'在你的程序以後的某個點仍然存在,即使'z'仍然如此 - 在這種情況下, 「id」甚至可能是完全不同對象的ID ......)。你爲什麼要這樣? – mgilson

+0

'id'是什麼意思?不,[文檔](https://docs.python.org/3.5/library/functions.html#zip)似乎是另有說明。請注意它們提供的等效代碼。 –

回答

3

這是理論上的可能在有限的情況下。你可能想要做的交互模式是這樣或pdb調試會話,如果它得到的一個對象,你忘了保持一個參考的唯一途徑,但它不是你應該在程序中曾經使用過的東西。

讓我們來看看有哪些引用zip迭代報告,垃圾收集器:

>>> import gc 
>>> gc.get_referents(zip([1], [2])) 
[(<list_iterator object at 0x7fcb4764dcf8>, <list_iterator object at 0x7fcb4764dbe0>), (None, None)] 

我們看到引用兩個基本迭代器的元組,和None秒的元組。 None的元組是優化的一部分zip用於節省分配輸出元組的時間。這對我們來說並不有趣。 list_iterator對象更有趣,但你要求列表,而不是列表迭代器。

在列表中的迭代器需要保持到列表的引用,因爲這可以參考在參考週期參與,列表迭代需要提出要求時,該報告引用了垃圾收集器。因此,如果我們再次使用gc.get_referents

>>> z = zip([1], [2]) 
>>> gc.get_referents(z) 
[(<list_iterator object at 0x7fcb4764db70>, <list_iterator object at 0x7fcb4764dd30>), (None, None)] 
>>> l_iters = _[0] 
>>> gc.get_referents(l_iters[0])[0] 
[1] 
>>> gc.get_referents(l_iters[1])[0] 
[2] 

我們可以檢索列表。

+0

哦精靈!我完全不需要那個*包裝類* –

+0

這非常棒。 – Aguy

0

zip不提供你所尋求的功能。

您可以改爲創建一個包裝類提供此功能:

class Zip: 

    def __init__(self, func=zip): 
     self.ids = None 
     self.func = func 

    def __call__(self, *args): 
     self.ids = [id(a) for a in args] 
     return self.func(*args) 

而且可以作爲這樣的:

>>> z = Zip() 
>>> l1 = [1, 2, 3, 4, 5] 
>>> l2 = ['a', 'b', 'c', 'd', 'e'] 
>>> list(z(l1, l2)) 
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')] 
>>> z.ids 
[52203152, 52334640] 

但是,不能保證在以後指向你的代碼,原始列表對象仍然擁有這些ID。