पाइथन में जिप (* [iter (s)] * n) कैसे काम करता है?


103
s = [1,2,3,4,5,6,7,8,9]
n = 3

zip(*[iter(s)]*n) # returns [(1,2,3),(4,5,6),(7,8,9)]

कैसे zip(*[iter(s)]*n)काम करता है ? यदि यह अधिक वर्बोज़ कोड के साथ लिखा जाता है तो यह कैसा दिखेगा?


1
यहाँ भी देखें कि यह कैसे काम करता है, यह भी बताया गया है: stackoverflow.com/questions/2202461/…
मैट जॉइनर

अगर यहाँ उत्तर पर्याप्त नहीं हैं, तो मैंने इसे यहाँ ब्लॉग किया: telliott99.blogspot.com/2010/01/…
telliott99

7
हालांकि बहुत ही पेचीदा, इस तकनीक को अजगर के मूल "पठनीयता" मूल्य के खिलाफ जाना चाहिए!
डेविस

जवाबों:


108

iter()एक अनुक्रम पर एक पुनरावृत्ति है। मात्रा की एक सूची, यानी लंबाई की एक सूची है , जहां प्रत्येक तत्व है [x] * nपैदा करता है । किसी फ़ंक्शन कॉल के लिए तर्कों में अनुक्रम को अनपैक करता है। इसलिए आप 3 बार एक ही पुनरावृत्ति पास कर रहे हैं , और यह हर बार पुनरावृत्त से एक आइटम खींचता है।nxnx*argzip()

x = iter([1,2,3,4,5,6,7,8,9])
print zip(x, x, x)

1
यह जानने के लिए अच्छा है: जब एक इट्रेटर एक आइटम yield(= returns) है, तो आप इस आइटम को "भस्म" के रूप में कल्पना कर सकते हैं। तो अगली बार जब इसे पुनरावृत्त कहा जाता है, तो यह अगले "अनकम्स्ड" आइटम का उत्पादन करता है।
winklerrr

46

अन्य महान जवाब और टिप्पणियां तर्क और ज़िप () को तर्क की भूमिकाओं को अच्छी तरह से समझाती हैं ।

जैसा कि इग्नासियो और ujukatzel कहते हैं, आप zip()एक ही पुनरावृत्ति के लिए तीन संदर्भों को पास करते हैं और zip()पूर्णांक के 3- नलिकाएं बनाते हैं - क्रम में - प्रत्येक संदर्भ से पुनरावृत्ति करने वाले के लिए:

1,2,3,4,5,6,7,8,9  1,2,3,4,5,6,7,8,9  1,2,3,4,5,6,7,8,9
^                    ^                    ^            
      ^                    ^                    ^
            ^                    ^                    ^

और जब से आप एक अधिक वर्बोज़ कोड नमूना मांगते हैं:

chunk_size = 3
L = [1,2,3,4,5,6,7,8,9]

# iterate over L in steps of 3
for start in range(0,len(L),chunk_size): # xrange() in 2.x; range() in 3.x
    end = start + chunk_size
    print L[start:end] # three-item chunks

के मूल्यों के बाद startऔर end:

[0:3) #[1,2,3]
[3:6) #[4,5,6]
[6:9) #[7,8,9]

FWIW, आप map()एक प्रारंभिक तर्क के साथ एक ही परिणाम प्राप्त कर सकते हैं None:

>>> map(None,*[iter(s)]*3)
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]

अधिक जानकारी के लिए zip()और map(): http://muffinresearch.co.uk/archives/2007/10/16/python-transposing-lists-with-map-and-zip/


31

मुझे लगता है कि एक बात जो सभी उत्तरों में याद आती है (शायद पुनरावृत्तियों से परिचित लोगों के लिए) लेकिन दूसरों के लिए इतनी स्पष्ट नहीं है -

चूंकि हमारे पास एक ही पुनरावृत्ति है, इसलिए इसका सेवन किया जाता है और शेष तत्वों का उपयोग जिप द्वारा किया जाता है। इसलिए अगर हम केवल सूची का उपयोग करते हैं और उदाहरण के लिए नहीं।

l = range(9)
zip(*([l]*3)) # note: not an iter here, the lists are not emptied as we iterate 
# output 
[(0, 0, 0), (1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5), (6, 6, 6), (7, 7, 7), (8, 8, 8)]

पुनरावृत्त का उपयोग करते हुए, मानों को पॉप करता है और केवल शेष उपलब्ध रहता है, इसलिए ज़िप के लिए एक बार 0 का उपयोग किया जाता है 1 उपलब्ध है और फिर 2 और इसी तरह। एक बहुत ही सूक्ष्म बात, लेकिन काफी चतुर !!!


+1, आपने मुझे बचाया! मुझे विश्वास नहीं हो रहा है कि अन्य उत्तर इस महत्वपूर्ण विवरण को छोड़ देते हैं और यह मानते हैं कि हर कोई यह जानता है। क्या आप किसी ऐसे दस्तावेज़ का संदर्भ दे सकते हैं जिसमें यह जानकारी शामिल हो?
स्नेहाशीष कर्मकार

9

iter(s) s के लिए पुनरावृति देता है।

[iter(s)]*n n की सूची को उसी के लिए पुनरावृत्त बनाता है।

इसलिए, करते समय zip(*[iter(s)]*n), यह सूची के सभी तीन पुनरावृत्तियों से एक आइटम को क्रम में निकालता है। चूँकि सभी पुनरावृत्तियाँ एक ही वस्तु हैं, इसलिए यह सूची को विखंडू में समूह बनाती है n


7
'एक ही सूची के n पुनरावृत्तियों' नहीं, लेकिन 'एक ही पुनरावृत्ति वस्तु'। जब वे एक ही सूची के होते हैं, तो विभिन्न इटैटर ऑब्जेक्ट राज्य साझा नहीं करते हैं।
थॉमस वॉटर

धन्यवाद, सही किया। वास्तव में यही मैं "सोच" रहा था, लेकिन कुछ और लिखा था।
स्टट्विस्टर

6

ज़िप का उपयोग करने के लिए सलाह का एक शब्द इस तरह से। यदि आपकी लंबाई समान रूप से विभाज्य नहीं है तो यह आपकी सूची को छोटा कर देगा। इसके आसपास काम करने के लिए आप या तो itertools.izip_longest का उपयोग कर सकते हैं यदि आप भरण मूल्यों को स्वीकार कर सकते हैं। या आप कुछ इस तरह का उपयोग कर सकते हैं:

def n_split(iterable, n):
    num_extra = len(iterable) % n
    zipped = zip(*[iter(iterable)] * n)
    return zipped if not num_extra else zipped + [iterable[-num_extra:], ]

उपयोग:

for ints in n_split(range(1,12), 3):
    print ', '.join([str(i) for i in ints])

प्रिंटों:

1, 2, 3
4, 5, 6
7, 8, 9
10, 11

3
यह पहले से ही itertoolsव्यंजनों में प्रलेखित है : docs.python.org/2/library/itertools.html#recipes grouper । पहिया को
मजबूत

1

यह शायद देखने के लिए क्या दुभाषिया या अजगर में हो रहा है आसान है ipythonके साथ n = 2:

In [35]: [iter("ABCDEFGH")]*2
Out[35]: [<iterator at 0x6be4128>, <iterator at 0x6be4128>]

तो, हमारे पास दो पुनरावृत्तियों की एक सूची है जो एक ही पुनरावृत्त वस्तु की ओर इशारा कर रहे हैं। याद रखें कि iterएक वस्तु पर एक पुनरावृत्ति वस्तु देता है और इस परिदृश्य में, यह *2अजगर के कारण दो बार एक ही पुनरावृत्ति करता है । Iterators भी केवल एक बार चलते हैं।

इसके अलावा, zipकिसी भी संख्या में पुनरावृत्तियों ( अनुक्रम पुनरावृत्त होते हैं ) और इनपुट अनुक्रमों में से प्रत्येक के i'th तत्व से ट्यूपल बनाता है। चूंकि दोनों पुनरावृत्तियां हमारे मामले में समान हैं, इसलिए आउटपुट के प्रत्येक 2-तत्व टपल के लिए ज़िप एक ही पुनरावृत्ति को दो बार स्थानांतरित करता है।

In [41]: help(zip)
Help on built-in function zip in module __builtin__:

zip(...)
    zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]

    Return a list of tuples, where each tuple contains the i-th element
    from each of the argument sequences.  The returned list is truncated
    in length to the length of the shortest argument sequence.

खोल ( *) ऑपरेटर सुनिश्चित है कि iterators थकावट जो इस मामले में जब तक वहाँ एक 2-तत्व टपल बनाने के लिए पर्याप्त इनपुट नहीं है करने के लिए चलाते हैं।

यह किसी भी मूल्य के लिए बढ़ाया जा सकता है nऔर zip(*[iter(s)]*n)वर्णित के रूप में काम करता है।


धीमा होने के लिए क्षमा करें। लेकिन क्या आप "2 पायथन सिंथैटिक शुगर के कारण एक ही पुनरावृत्ति दो बार समझा सकते हैं। Iterators भी एक बार चलते हैं।" कृपया भाग लें? यदि हां, तो परिणाम कैसे आया है [("ए", "ए") ....]? धन्यवाद।
बोवेन लियू

@BowenLiu *किसी वस्तु को डुप्लिकेट करने के लिए बस सुविधा है। इसे स्केलर के साथ और फिर सूचियों के साथ आज़माएं। इसके अलावा print(*zip(*[iter("ABCDEFG")]*2))बनाम प्रयास करें print(*zip(*[iter("ABCDEFG"), iter("ABCDEFG")]))। फिर दो चरणों को छोटे चरणों में फाड़ना शुरू करें ताकि यह देखा जा सके कि दो बयानों में वास्तव में पुनरावृत्त वस्तुएं क्या हैं।
अखाड़ा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.