टपल की सूची को कई सूचियों में कैसे बदलें?


108

मान लीजिए कि मेरे पास ट्यूपल्स की सूची है और मैं कई सूचियों में परिवर्तित करना चाहता हूं।

उदाहरण के लिए, टुपल्स की सूची है

[(1,2),(3,4),(5,6),]

क्या पायथन में कोई अंतर्निहित कार्य है जो इसे परिवर्तित करता है:

[1,3,5],[2,4,6]

यह एक सरल कार्यक्रम हो सकता है। लेकिन मैं पायथन में इस तरह के अंतर्निहित फ़ंक्शन के अस्तित्व के बारे में उत्सुक हूं।

जवाबों:


162

अंतर्निहित कार्य zip()लगभग वही करेगा जो आप चाहते हैं:

>>> zip(*[(1, 2), (3, 4), (5, 6)])
[(1, 3, 5), (2, 4, 6)]

फर्क सिर्फ इतना है कि आपको सूचियों के बजाय ट्यूपल्स मिलते हैं। आप उन्हें उपयोग करके सूचियों में बदल सकते हैं

map(list, zip(*[(1, 2), (3, 4), (5, 6)]))

40

से अजगर डॉक्स :

zip () * ऑपरेटर के साथ मिलकर किसी सूची को अनज़िप करने के लिए इस्तेमाल किया जा सकता है:

विशिष्ट उदाहरण:

>>> zip((1,3,5),(2,4,6))
[(1, 2), (3, 4), (5, 6)]
>>> zip(*[(1, 2), (3, 4), (5, 6)])
[(1, 3, 5), (2, 4, 6)]

या, यदि आप वास्तव में सूची चाहते हैं:

>>> map(list, zip(*[(1, 2), (3, 4), (5, 6)]))
[[1, 3, 5], [2, 4, 6]]


4

franklsf95 उनके जवाब में प्रदर्शन के लिए जाता है और उनके लिए चयन करता है list.append(), लेकिन वे इष्टतम नहीं हैं।

सूची समझ जोड़ना, मैं निम्नलिखित के साथ समाप्त हुआ:

def t1(zs):
    xs, ys = zip(*zs)
    return xs, ys

def t2(zs):
    xs, ys = [], []
    for x, y in zs:
        xs.append(x)
        ys.append(y)
    return xs, ys

def t3(zs):
    xs, ys = [x for x, y in zs], [y for x, y in zs]
    return xs, ys

if __name__ == '__main__':
    from timeit import timeit
    setup_string='''\
N = 2000000
xs = list(range(1, N))
ys = list(range(N+1, N*2))
zs = list(zip(xs, ys))
from __main__ import t1, t2, t3
'''
    print(f'zip:\t\t{timeit('t1(zs)', setup=setup_string, number=1000)}')
    print(f'append:\t\t{timeit('t2(zs)', setup=setup_string, number=1000)}')
    print(f'list comp:\t{timeit('t3(zs)', setup=setup_string, number=1000)}')

इसने परिणाम दिया:

zip:            122.11585397789766
append:         356.44876132614047
list comp:      144.637765085659

इसलिए यदि आप प्रदर्शन के बाद हैं, तो आपको संभवतः उपयोग करना चाहिए, zip()हालांकि सूची की समझ बहुत पीछे नहीं है। appendतुलना में प्रदर्शन वास्तव में बहुत खराब है।


1

*zipअधिक पायथोनिक होने के बावजूद , निम्नलिखित कोड में बेहतर प्रदर्शन है:

xs, ys = [], []
for x, y in zs:
    xs.append(x)
    ys.append(y)

इसके अलावा, जब मूल सूची zsखाली *zipहोगी , तो उठाएंगे, लेकिन यह कोड ठीक से संभाल सकता है।

मैंने अभी एक त्वरित प्रयोग किया है, और यहाँ परिणाम है:

Using *zip:     1.54701614s
Using append:   0.52687597s

इसे कई बार चलाने appendसे 3x - 4x तेज होता है zip! परीक्षण स्क्रिप्ट यहाँ है:

#!/usr/bin/env python3
import time

N = 2000000
xs = list(range(1, N))
ys = list(range(N+1, N*2))
zs = list(zip(xs, ys))

t1 = time.time()

xs_, ys_ = zip(*zs)
print(len(xs_), len(ys_))

t2 = time.time()

xs_, ys_ = [], []
for x, y in zs:
    xs_.append(x)
    ys_.append(y)
print(len(xs_), len(ys_))

t3 = time.time()

print('Using *zip:\t{:.8f}s'.format(t2 - t1))
print('Using append:\t{:.8f}s'.format(t3 - t2))

मेरा पायथन संस्करण:

Python 3.6.3 (default, Oct 24 2017, 12:18:40)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

1

क्लाउडीयू के जवाब के अलावा, आप इसका उपयोग कर सकते हैं:

>>>a, b = map(list, zip(*[(1, 2), (3, 4), (5, 6)]))
>>>a
[1,3,5]
>>>b
[2,4,6]

@Peyman mohseni kiasari के अनुसार संपादित


1
नहीं! यह आपको देगा (1, 3, 5)और (2, 4, 6)सूचियों को नहीं। आप का उपयोग करना चाहिएmap(list, zip(*[(1, 2), (3, 4), (5, 6)]))
Peyman

0

क्लॉडिउ और क्लॉडिउ के उत्तर को जोड़ना और चूंकि मानचित्र को 3 पायथन में itertools से आयात करने की आवश्यकता है, आप भी इस तरह की एक सूची का उपयोग करते हैं:

[[*x] for x in zip(*[(1,2),(3,4),(5,6)])]
>>> [[1, 3, 5], [2, 4, 6]]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.