টিপলগুলির তালিকাটিকে একাধিক তালিকায় কীভাবে রূপান্তর করবেন?


108

ধরুন আমার কাছে টিপলসের একটি তালিকা রয়েছে এবং আমি একাধিক তালিকায় রূপান্তর করতে চাই।

উদাহরণস্বরূপ, tuples তালিকা হয়

[(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((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

এটি একাধিকবার চালানো, append3x - 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]

@ পাইমন মোহসেনী কিসারি অনুসারে সম্পাদিত


1
না! এটি আপনাকে দেবে (1, 3, 5)এবং (2, 4, 6)তালিকা দেবে না। আপনার ব্যবহার করা উচিতmap(list, zip(*[(1, 2), (3, 4), (5, 6)]))
পেইম্যান

0

ক্লাউডিউ এবং ক্লাউডির উত্তরে যুক্ত করা এবং যেহেতু অজগর 3 তে মানচিত্রটি ইয়ারটুলগুলি থেকে আমদানি করা দরকার, আপনিও একটি তালিকা বোধগম্যতা ব্যবহার করুন:

[[*x] for x in zip(*[(1,2),(3,4),(5,6)])]
>>> [[1, 3, 5], [2, 4, 6]]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.