ट्रांसपोज़र/अनजिप फ़ंक्शन (ज़िप के विपरीत)?


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) पर भी देखें 03 mar. 152015-03-03 13:17:26

+1

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

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

ओह, अगर केवल इतना आसान था। अनजिपिंग 'ज़िप ([], [])' इस तरह से आपको '[], [] 'प्राप्त नहीं होता है। यह आपको '[]' मिलता है। अगर केवल ... 24 feb. 142014-02-24 12:06:58

  0

@ user2357112 यह आपको 'ज़िप (* ज़िप ([list1], [list2]) देता है)' आपको '([list1, list2]) देता है। 25 feb. 142014-02-25 21:50:13

  0

@cdhagmann: 'ज़िप ([list1], [list2]) 'कभी भी आप जो चाहते हैं वह नहीं है। यह आपको '[सूची 1, सूची 2)] देता है। 25 feb. 142014-02-25 22:05:47

  0

@ user2357112 मैं सूची 1 नाम की किसी भी सूची का मतलब 'सूची [1] 1 का उपयोग कर रहा था, न कि सूची के साथ केवल एक सूची के साथ सूची के साथ सूची के रूप में। तो 'list1 = [1,2,3,4] 'और' list2 = [1,2,3,4] 'दिया गया है, फिर' ज़िप (* ज़िप (सूची 1, सूची 2))' आपको देता है '([1 , 2,3,4], [1,2,3,4]) ' 25 feb. 142014-02-25 22:31:06

+1

@cdhagmann: अब 'list1 = [] के साथ प्रयास करें; List2 = [] '। 26 feb. 142014-02-26 02:53:43

  0

@cdhagmann आपको अपने आदेशों से [(1, 2, 3, 4), (1, 2, 3, 4)] मिलता है। 03 jul. 142014-07-03 13:07:52

+1

यह पायथन 3 में काम नहीं करता है। देखें: http://stackoverflow.com/questions/24590614/python3-unzipping-a-list-of-tuples 05 jul. 142014-07-05 21:35:16

  0

ज़िप लंबे समय तक तत्वों को संरक्षित नहीं करता है, इसलिए पैडिंग आवश्यक है 21 sep. 142014-09-21 06:03:50

  0

'tuple (मानचित्र (सूची, ज़िप (* मूल))) 'सटीक परिणाम प्राप्त करने के लिए। 30 jan. 152015-01-30 04:26:57

+4

@ टॉमी यह गलत है। 'ज़िप' वास्तव में पाइथन 3 में समान कार्य करता है सिवाय इसके कि यह एक सूची के बजाय एक पुनरावर्तक देता है। उपरोक्त के समान आउटपुट प्राप्त करने के लिए आपको केवल एक सूची में ज़िप कॉल को लपेटने की आवश्यकता है: 'सूची (ज़िप (* [(' ए ', 1), (' बी ', 2), (' सी ', 3), ('डी', 4)])) 'उत्पादन करेगा' [('ए', 'बी', 'सी', 'डी'), (1, 2, 3, 4)] ' 11 mar. 152015-03-11 14:11:12

+1

नोटिस: आप बहुत लंबी सूचियों के साथ स्मृति और प्रदर्शन मुद्दों को पूरा कर सकते हैं। 14 oct. 162016-10-14 12:44:09

  0

यह एक शानदार जवाब है। :) 16 may. 172017-05-16 19:00:59


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 ... सामान्य रूप से, सूची समझें तुरंत विस्तारित की जाती हैं - या क्या मुझे कुछ गलत लगता है? 15 aug. 112011-08-15 19:52:57

  0

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

+8

आपको जो उम्मीद है वह जनरेटर एक्सप्रेशन है - जो पहले से मौजूद है। 15 oct. 122012-10-15 13:12:19

  0

नहीं, मुझे जो उम्मीद है वह बारहमासी पसंदीदा "पर्याप्त स्मार्ट कंपाइलर" (या इस मामले में दुभाषिया) है। मुझे नहीं लगता कि वहां कुछ भी समझदार है जो कोड के बाहर बीजीबस का विश्लेषण करके और कुछ अलग तरीके से अलग करके टूट जाएगा। (आलसी संग्रह बनाने की तरह) पायथन ने कभी भी इस सुविधा का वादा नहीं किया है, और शायद इसकी संभावना कभी नहीं होगी, लेकिन मैं उस सपने को डिजाइन में देख सकता हूं। स्केल बेहतर के लिए 18 oct. 122012-10-18 07:11:03

  0

+1। 19 jul. 132013-07-19 10:59:09

+11

यह 'ज़िप (* x)' संस्करण की तुलना में 'बेहतर स्केल' नहीं करता है। 'ज़िप (* एक्स) 'को केवल लूप के माध्यम से एक पास की आवश्यकता होती है, और स्टैक तत्वों का उपयोग नहीं करती है। 17 nov. 132013-11-17 16:38:20

+1

चाहे वह "बेहतर पैमाने पर" हो या नहीं, ट्रांसपोज़ड डेटा की तुलना में मूल डेटा के जीवन चक्र पर निर्भर करता है। यह उत्तर केवल 'ज़िप' का उपयोग करने से बेहतर है यदि उपयोग-मामला यह है कि ट्रांसपोज़ड डेटा का उपयोग किया जाता है और तत्काल त्याग दिया जाता है, जबकि मूल सूचियां बहुत अधिक समय तक स्मृति में रहती हैं। 15 nov. 152015-11-15 06:55:50


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

दिलचस्प, क्या आप समझा सकते हैं कि 'नक्शा' कैसे काम करता है? 26 sep. 132013-09-26 15:53:09

+4

आप python3 उपयोगकर्ताओं के लिए 'izip_longest' 26 sep. 132013-09-26 16:52:55

+2

' zip_longest' के रूप में भी जाना जा सकता है। 08 mar. 162016-03-08 09:02:13

  0

@GrijeshChauhan मुझे पता है कि यह वास्तव में पुराना है, लेकिन यह सुविधा में एक अजीब बनाया गया है: https://docs.python.org/2/library/functions.html#map "यदि फ़ंक्शन कोई नहीं है, तो पहचान फ़ंक्शन माना जाता है; यदि कई तर्क हैं, तो नक्शा() एक सूची देता है जिसमें सभी पुनरावृत्तियों (एक प्रकार का ट्रांज़ेक्शन ऑपरेशन) से संबंधित आइटम शामिल होते हैं। पुनरावृत्त तर्क अनुक्रम या किसी भी पुनरावृत्त वस्तु हो सकते हैं; परिणाम हमेशा एक सूची होती है। " 14 jul. 172017-07-14 19:26:37

  0

@ cactus1 धन्यवाद, सहायक, उस समय मैं पाइथन सीख रहा था 15 jul. 172017-07-15 04:42:25


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)] 

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