programing

튜플 목록을 여러 목록으로 변환하는 방법은 무엇입니까?

nasanasas 2020. 9. 7. 08:13
반응형

튜플 목록을 여러 목록으로 변환하는 방법은 무엇입니까?


튜플 목록이 있고 여러 목록으로 변환하고 싶다고 가정합니다.

예를 들어, 튜플 목록은 다음과 같습니다.

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

Python에 다음과 같이 변환하는 내장 함수가 있습니까?

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

이것은 간단한 프로그램이 될 수 있습니다. 그러나 나는 파이썬에 그러한 내장 함수가 존재하는지 궁금합니다.


내장 함수 zip()는 거의 원하는 작업을 수행합니다.

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

유일한 차이점은 목록 대신 튜플을 얻는다는 것입니다. 다음을 사용하여 목록으로 변환 할 수 있습니다.

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

로부터 파이썬 문서 :

* 연산자와 함께 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]]

사용하다:

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

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

So if you are after performance, you should probably use zip() although list comprehensions are not too far behind. The performance of append is actually pretty poor in comparison.


Adding to Claudiu's and Claudiu's answer and since map needs to be imported from itertools in python 3, you also use a list comprehension like:

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

Despite *zip being more Pythonic, the following code has much better performance:

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

Also, when the original list zs is empty, *zip will raise, but this code can properly handle.

I just ran a quick experiment, and here is the result:

Using *zip:     1.54701614s
Using append:   0.52687597s

Running it multiple times, append is 3x - 4x faster than zip! The test script is here:

#!/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))

My Python Version:

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.

In addition to Claudiu's answer, you can use:

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

Edited according to @Peyman mohseni kiasari

참고URL : https://stackoverflow.com/questions/8081545/how-to-convert-list-of-tuples-to-multiple-lists

반응형