2012-06-12 22 views
5

दोनों सूची और islice ऑब्जेक्ट्स पुन: प्रयोज्य हैं लेकिन परिणाम में यह अंतर क्यों है।itertools लाइब्रेरी से tee function

r = [1, 2, 3, 4]    
i1, i2 = tee(r) 
print [e for e in r if e < 3] 
print [e for e in i2] 
#[1, 2] 
#[1, 2, 3, 4] 


r = islice(count(), 1, 5)   
i1, i2 = tee(r) 
print [e for e in r if e < 3] 
print [e for e in i2] 
#[1, 2] 
#[] 

उत्तर

14

यहां मुद्दा यह है कि tee() जरूरतों मूल पुनरावर्तक से मूल्यों का उपभोग करने, अगर आप उन्हें मूल पुनरावर्तक से लेने शुरू करते हैं, यह ठीक से काम नहीं होगा। आपकी सूची उदाहरण में, पुनरावृत्ति बस शुरू होता है। जेनरेटर उदाहरण में, यह थक गया है और कोई और मूल्य नहीं बनाया जाता है।

यह अच्छी तरह से प्रलेखित:

एक बार टी

() एक विभाजन, मूल iterable कहीं और नहीं किया जाना चाहिए बना दिया है; अन्यथा, टीई वस्तुओं को सूचित किए बिना पुनरावृत्त उन्नत हो सकता है।

Source

संपादित एक सूची और एक जनरेटर के बीच अंतर में बिंदु को वर्णन:

>>> from itertools import islice, count 
>>> a = list(range(5)) 
>>> b = islice(count(), 0, 5) 
>>> a 
[0, 1, 2, 3, 4] 
>>> b 
<itertools.islice object at 0x7fabc95d0fc8> 
>>> for item in a: 
...  print(item) 
... 
0 
1 
2 
3 
4 
>>> for item in a: 
...  print(item) 
... 
0 
1 
2 
3 
4 
>>> for item in b: 
...  print(item) 
... 
0 
1 
2 
3 
4 
>>> for item in b: 
...  print(item) 
... 
>>> 
+0

लेकिन सूची वस्तु और islice वस्तु समान व्यवहार करने की जरूरत है, है ना? – John

+1

@ जॉन नंबर, जब आप सूची में लूप करते हैं, तो आपको हर बार एक नया इटरेटर मिल जाता है, जिसका अर्थ है कि आपको अभी भी मान मिलते हैं। जब आप 'इस्लिस()' का उपयोग करते हैं तो आपको जनरेटर मिलता है, जो एक बार मूल्यों का उत्पादन करेगा, और फिर समाप्त हो जाएगा। इसे स्वयं आज़माएं - बस दो बार सूची में लूप करें, फिर उस पर एक आईलिस और लूप लें - व्यवहार में अंतर देखें। –

+0

@ जॉन दो उदाहरणों को समान रूप से व्यवहार करने के लिए, 'r = [1,2,3,4]' के बजाय 'r = iter ([1,2,3,4]) 'का उपयोग करें। – clacke

0

अपने सूची comprehensions में, आप i1 साथ r बदलना चाहते हैं।