2008-08-21 25 views
342

मेरे पास 2-आइटम टुपल्स की एक सूची है और मैं उन्हें 2 सूचियों में परिवर्तित करना चाहता हूं जहां पहले प्रत्येक टुपल में पहला आइटम होता है और दूसरी सूची में दूसरा आइटम होता है।ट्रांसपोज़र/अनजिप फ़ंक्शन (ज़िप के विपरीत)?

उदाहरण के लिए:

original = [('a', 1), ('b', 2), ('c', 3), ('d', 4)] 
# and I want to become... 
result = (['a', 'b', 'c', 'd'], [1, 2, 3, 4]) 

वहाँ एक builtin समारोह है कि करता है कि है?

+3

नीचे दिए गए महान उत्तर, लेकिन [numpy's transpose] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.transpose.html) पर भी देखें – opyate

+1

ऐसा करने के लिए यह अच्छा जवाब देखें सूची के बजाय जेनरेटर: [कैसे-टू-अनजिप-ए-इटरेटर] (http://stackoverflow.com/questions/30805000/how-to-unzip-an-iterator) – YvesgereY

उत्तर

546

zip इसका अपना उलटा है! बशर्ते आप विशेष * ऑपरेटर का उपयोग करें।

>>> zip(*[('a', 1), ('b', 2), ('c', 3), ('d', 4)]) 
[('a', 'b', 'c', 'd'), (1, 2, 3, 4)] 

तरीका यह काम करता है तर्क के साथ zip फोन करके है:

zip(('a', 1), ('b', 2), ('c', 3), ('d', 4)) 

... तर्कों (एक टपल में बदला जा रहा करने के बाद) zip सीधे करने के लिए पारित कर रहे हैं को छोड़कर, तो चिंता करने की कोई आवश्यकता नहीं है तर्कों की संख्या के बारे में बहुत बड़ा हो रहा है।

+6

ओह, अगर केवल इतना आसान था। अनजिपिंग 'ज़िप ([], [])' इस तरह से आपको '[], [] 'प्राप्त नहीं होता है। यह आपको '[]' मिलता है। अगर केवल ... – user2357112

+0

@ user2357112 यह आपको 'ज़िप (* ज़िप ([list1], [list2]) देता है)' आपको '([list1, list2]) देता है। – cdhagmann

+0

@cdhagmann: 'ज़िप ([list1], [list2]) 'कभी भी आप जो चाहते हैं वह नहीं है। यह आपको '[सूची 1, सूची 2)] देता है। – user2357112

22

तुम भी बेहतर

result = ([ a for a,b in original ], [ b for a,b in original ]) 

यह चाहिए पैमाने कर सकता है। विशेष रूप से यदि पायथन आवश्यक होने तक सूची समझों का विस्तार न करने पर अच्छा बनाता है।

(संयोग से, यह सूची के एक 2-टपल (जोड़ी), बजाय tuples की एक सूची बनाता है, zip करता है।)

वास्तविक सूचियों के बजाय जनरेटर ठीक लगता है, यह है कि क्या करना होगा:

result = ((a for a,b in original), (b for a,b in original)) 

जनरेटर सूची के माध्यम से तब तक नहीं निकलते जब तक आप प्रत्येक तत्व के लिए नहीं पूछते, लेकिन दूसरी तरफ, वे मूल सूची के संदर्भ रखते हैं।

+6

"विशेष रूप से यदि पायथन आवश्यक होने तक सूची समझों का विस्तार न करने पर अच्छा बनाता है।" mmm ... सामान्य रूप से, सूची समझें तुरंत विस्तारित की जाती हैं - या क्या मुझे कुछ गलत लगता है? – glglgl

+0

@glglgl: नहीं, आप शायद सही हैं। मैं बस उम्मीद कर रहा था कि कुछ भविष्य का संस्करण सही काम करना शुरू कर सकता है। (यह बदलने के लिए असंभव नहीं है, साइड-इफेक्ट सेमेन्टिक्स जिन्हें परिवर्तन की आवश्यकता है, शायद पहले ही निराश हो चुके हैं।) –

+8

आपको जो उम्मीद है वह जनरेटर एक्सप्रेशन है - जो पहले से मौजूद है। – glglgl

19

यदि आपके पास ऐसी सूचियां हैं जो समान लंबाई नहीं हैं, तो आप Patricks उत्तर के अनुसार ज़िप का उपयोग नहीं करना चाहेंगे। यह काम करता है:

>>> zip(*[('a', 1), ('b', 2), ('c', 3), ('d', 4)]) 
[('a', 'b', 'c', 'd'), (1, 2, 3, 4)] 

लेकिन अलग अलग लंबाई सूचियों के साथ, ज़िप कम से कम सूची की लंबाई के प्रत्येक आइटम ट्रंकेटस:

>>> zip(*[('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e',)]) 
[('a', 'b', 'c', 'd', 'e')] 

आप कोई समारोह के साथ मानचित्र का उपयोग कर सकते हैं कोई नहीं के साथ खाली परिणाम को भरने के लिए:

>>> map(None, *[('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e',)]) 
[('a', 'b', 'c', 'd', 'e'), (1, 2, 3, 4, None)] 

ज़िप() हालांकि मामूली तेज़ है।

def unzip(iterable): 
    return zip(*iterable) 

मैं unzip अधिक पठनीय लगता है:

+3

दिलचस्प, क्या आप समझा सकते हैं कि 'नक्शा' कैसे काम करता है? –

+4

आप python3 उपयोगकर्ताओं के लिए 'izip_longest' – Marcin

+2

' zip_longest' के रूप में भी जाना जा सकता है। – zezollo

11

मैं zip(*iterable) उपयोग करने के लिए इतनी के रूप में मेरे कार्यक्रमों में (जो कोड का टुकड़ा आप के लिए देख रहे हैं) की तरह।

2

यह यह करने के लिए केवल एक और तरीका है, लेकिन यह मेरे लिए एक बहुत मदद की तो मैं इसे यहाँ लिख दिया गया है:

X=[1,2,3,4] 
Y=['a','b','c','d'] 
XY=zip(X,Y) 

में परिणामी:

In: XY 
Out: [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')] 

इस डेटा संरचना करने के बाद इसे अनजिप करने और मूल पर वापस जाने के लिए अधिक पाइथोनिक तरीका यह मेरी राय में है:

x,y=zip(*XY) 

लेकिन यह एक टपल लौट इसलिए यदि आप एक सरणी की जरूरत है आप का उपयोग कर सकते हैं:

xy=(list(x),list(y)) 
7
>>> original = [('a', 1), ('b', 2), ('c', 3), ('d', 4)] 
>>> tuple([list(tup) for tup in zip(*original)]) 
(['a', 'b', 'c', 'd'], [1, 2, 3, 4]) 

प्रश्न में के रूप में सूची के एक टपल देता है।

list1, list2 = [list(tup) for tup in zip(*original)] 

दो सूचियों को अनपैक करता है।