"튜플 목록"을 일반 목록 또는 행렬로 변환


82

Sqlite를 사용하면 "select..from"명령은 결과 "출력"을 반환하며 다음과 같이 인쇄합니다 (python).

>>print output
[(12.2817, 12.2817), (0, 0), (8.52, 8.52)]

튜플 목록 인 것 같습니다. 간단한 1D 배열로 "출력"을 변환하고 싶습니다 (= 파이썬의 목록).

[12.2817, 12.2817, 0, 0, 8.52, 8.52]

또는 2x3 매트릭스 :

12.2817 12.2817
0          0 
8.52     8.52

"output [i] [j]"를 통해 읽음

flatten 명령은 첫 번째 옵션에 대한 작업을 수행하지 않으며 두 번째 옵션에 대해서는 전혀 모릅니다 ... :)

힌트를 주시겠습니까? 실제 데이터가 훨씬 더 크기 때문에 빠른 것이 좋습니다 (여기에 간단한 예가 있습니다).


2
[(12.2817, 12.2817), (0, 0), (8.52, 8.52)]이미 3x2 행렬입니다!? 아니면 내가 뭔가를 놓친거야?
mouad


1
flatten 함수 확인 itertools 모듈 레시피에는 이미 flatten 함수 예제가 있습니다. docs.python.org/library/itertools.html#recipes
mouad

4
[item for sublist in output for item in sublist]완벽하게 작동하며 내부 튜플도 목록이 될 수 있다는 장점이 있습니다. 보다 일반적으로 내부 및 외부 반복 작업의 조합
Kyss Tao

답변:


125

지금까지 가장 빠르고 가장 짧은 솔루션이 게시되었습니다.

list(sum(output, ()))

itertools솔루션 보다 약 50 % 빠르며 솔루션 보다 약 70 % 빠릅니다 map.


8
@Joel 멋지지만 어떻게 작동하는지 궁금해? list(output[0]+output[1]+output[2])원하는 결과를 제공하지만 list(sum(output))그렇지 않습니다. 왜? ()는 어떤 "마법"을합니까?
Kyss Tao 2013

9
좋아, 나는 매뉴얼 g를 읽었어야했다 . 그것은 같다 sum(sequence[, start]): 합계가 존재하는 경우 시작 하여 나머지 요소를 추가하는 대신 start기본값을 추가합니다. 널 귀찮게해서 미안해. 0sequence[0]
Kyss Tao 2013

3
이것은 잘 알려진 반 패턴입니다. sum시퀀스를 연결 하는 데 사용하지 마십시오 . 2 차 시간 알고리즘이 생성됩니다. 사실, sum문자열로 이것을 시도하면 함수가 불평 할 것입니다!
juanpa.arrivillaga

@ juanpa.arrivillaga : 동의했습니다. 이것이 바람직한 사용 사례는 거의 없습니다.
Joel Cornett 2018

9
예, 빠르지 만 완전히 둔감합니다. 실제로 무엇을하고 있는지에 대한 의견을 남겨야합니다. (
CpILL

42

Iterable 유형과 함께 작동하고 여기에 표시된 다른 방법보다 빠른 목록 이해 접근 방식입니다.

flattened = [item for sublist in l for item in sublist]

l병합 할 목록입니다 ( outputOP의 경우 호출 됨 ).


timeit 테스트 :

l = list(zip(range(99), range(99)))  # list of tuples to flatten

목록 이해

[item for sublist in l for item in sublist]

timeit 결과 = 루프 당 7.67µs ± 129ns

목록 extend () 메서드

flattened = []
list(flattened.extend(item) for item in l)

timeit 결과 = 루프 당 11µs ± 433ns

합집합()

list(sum(l, ()))

timeit 결과 = 루프 당 24.2µs ± 269ns


1
나는 이것을 큰 데이터 세트에서 사용해야했는데, 목록 이해 방법이 훨씬 빠릅니다!
nbeuchat

.extend 솔루션에 약간의 변경을가했고 이제는 조금 더 잘 수행됩니다. 시간에 확인해보세요 비교하기
Totoro 2018

24

Python 2.7 및 모든 버전의 Python3에서 이터 러블 itertools.chain목록을 평면화하는 데 사용할 수 있습니다 . 중 하나와 *구문이나 클래스 방법.

>>> t = [ (1,2), (3,4), (5,6) ]
>>> t
[(1, 2), (3, 4), (5, 6)]
>>> import itertools
>>> list(itertools.chain(*t))
[1, 2, 3, 4, 5, 6]
>>> list(itertools.chain.from_iterable(t))
[1, 2, 3, 4, 5, 6]

11

업데이트 : 확장을 사용하지만 이해하지 않고 목록을 반복자로 사용하지 않고 병합 (가장 빠름)

목록 이해를 통해 더 빠른 솔루션을 제공 한 이것에 대한 다음 답변을 확인한 후 dual for약간의 조정을 수행했으며 이제 더 잘 수행됩니다. 먼저 list (...) 실행은 많은 시간을 끌고 목록을 변경했습니다. 간단한 루프에 대한 이해도 조금 더 깎였습니다.

새로운 솔루션은 다음과 같습니다.

l = []
for row in output: l.extend(row)

이전 :

지도 / 확장으로 병합 :

l = []
list(map(l.extend, output))

지도 대신 목록 이해력으로 병합

l = []
list(l.extend(row) for row in output)

새로운 확장에 대한 일부 timeits 및 [...]에 대한 list (...)를 제거하여 개선되었습니다.

import timeit
t = timeit.timeit
o = "output=list(zip(range(1000000000), range(10000000))); l=[]"
steps_ext = "for row in output: l.extend(row)"
steps_ext_old = "list(l.extend(row) for row in output)"
steps_ext_remove_list = "[l.extend(row) for row in output]"
steps_com = "[item for sublist in output for item in sublist]"

print("new extend:      ", t(steps_ext, setup=o, number=10))
print("old extend w []: ", t(steps_ext_remove_list, setup=o, number=10))
print("comprehension:   ", t(steps_com, setup=o, number=10,))
print("old extend:      ", t(steps_ext_old, setup=o, number=10))

>>> new extend:       4.502427191007882
>>> old extend w []:  5.281140706967562
>>> comprehension:    5.54302118299529
>>> old extend:       6.840151469223201    

9

사용 itertools체인 :

>>> import itertools
>>> list(itertools.chain.from_iterable([(12.2817, 12.2817), (0, 0), (8.52, 8.52)]))
[12.2817, 12.2817, 0, 0, 8.52, 8.52]

7
>>> flat_list = []
>>> nested_list = [(1, 2, 4), (0, 9)]
>>> for a_tuple in nested_list:
...     flat_list.extend(list(a_tuple))
... 
>>> flat_list
[1, 2, 4, 0, 9]
>>> 

위와 같이 튜플 목록에서 단일 목록으로 쉽게 이동할 수 있습니다.



5

이것은 numpy데이터 구조와 속도 측면 모두에서 만들어진 것입니다.

import numpy as np

output = [(12.2817, 12.2817), (0, 0), (8.52, 8.52)]
output_ary = np.array(output)   # this is your matrix 
output_vec = output_ary.ravel() # this is your 1d-array

2

임의의 중첩 목록의 경우 (경우에 따라) :

def flatten(lst):
    result = []
    for element in lst: 
        if hasattr(element, '__iter__'):
            result.extend(flatten(element))
        else:
            result.append(element)
    return result

>>> flatten(output)
[12.2817, 12.2817, 0, 0, 8.52, 8.52]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.