트랜스/압축 해제 기능을(역 zip)?
문제
나의 목록을 가지고 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])
은 거기에 기본 제공 기능는 무엇입니까?
해결책
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
바로(후 변환 tuple),그래서 거기에 대해 걱정할 필요가 없는 숫자의 인수를 받고 너무 큽니다.
다른 팁
할 수 있도
result = ([ a for a,b in original ], [ b for a,b in original ])
그 야 규모를 더합니다.특히 경우에는 파이썬 게 좋은지 확대하고 목록을 함축하지 않는 한 필요합니다.
(덧붙여,그것은 2-tuple(pair)목록보다는 목록의 튜플아 zip
는 않습니다.)
는 경우 발전기 대신 실제 목록을 확인하고,이 것이 그렇게 하도록 요청합니다.
result = (( a for a,b in original ), ( b for a,b in original ))
발전기하지 않는 뭉크를 통해 목록할 때까지 요청에 대한 각각의 요소,하지만 다른 한편으로,그들은 그 유지를 참조하여 원래의 목록입니다.
이 있는 경우 목록되지 않은 동일한 길이 있지 않을 사용하고 싶으로 우편당 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)]
zip()를 약간 더 빠르게 하지만입니다.
나 zip(*iterable)
(는 조각의 코드고)내에서 프로그램으로도록:
def unzip(iterable):
return zip(*iterable)
내가 찾기 unzip
더 읽을 수 있습니다.
>>> 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)]
의 압축을 풉 두 개의 목록입니다.
그것은 단지 그것을 할 수있는 또 다른 방법이지만 그것이 나에게 많은 도움이 그래서 나는 그것을 쓰는 여기:
이 데이터 구조:
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')]
더 pythonic 방법으로 압축을 해제하고 원하는 것 이 중 하나에 내 의견:
x,y=zip(*XY)
하지만 이 반환 튜플 그래서 당신은 목록이 필요할 수 있는 사용:
x,y=(list(x),list(y))
순진한 접근 방식
def transpose_finite_iterable(iterable):
return zip(*iterable) # `itertools.izip` for Python 2 users
잘 작동을 위한 유한 반복 가능한(예:같은 시퀀스 list
/tuple
/str
의)(잠재적으로 무한한)iterables 할 수 있는 도시아
| |a_00| |a_10| ... |a_n0| |
| |a_01| |a_11| ... |a_n1| |
| |... | |... | ... |... | |
| |a_0i| |a_1i| ... |a_ni| |
| |... | |... | ... |... | |
가
n in ℕ
,a_ij
에 해당하는j
번째 요소의i
-일 반복 가능한,
후 및 적용 transpose_finite_iterable
우리가 얻
| |a_00| |a_01| ... |a_0i| ... |
| |a_10| |a_11| ... |a_1i| ... |
| |... | |... | ... |... | ... |
| |a_n0| |a_n1| ... |a_ni| ... |
Python 의 예는 경우 a_ij == j
, n == 2
>>> from itertools import count
>>> iterable = [count(), count()]
>>> result = transpose_finite_iterable(iterable)
>>> next(result)
(0, 0)
>>> next(result)
(1, 1)
하지만 우리가 사용할 수 없 transpose_finite_iterable
다시 돌아가려면의 구조를 원 iterable
기 result
무한 반복 가능한 유한 iterables(tuple
s 에서 우리의 경우):
>>> transpose_finite_iterable(result)
... hangs ...
Traceback (most recent call last):
File "...", line 1, in ...
File "...", line 2, in transpose_finite_iterable
MemoryError
그래서 우리는 어떻게 다루는 경?
...그리고 여기에 제공 deque
후에 우리를 살펴 문의 itertools.tee
기능, 가,Python 는 조리법으로 일부 수정할 수 있는 도움말에서 우리의 케이스
def transpose_finite_iterables(iterable):
iterator = iter(iterable)
try:
first_elements = next(iterator)
except StopIteration:
return ()
queues = [deque([element])
for element in first_elements]
def coordinate(queue):
while True:
if not queue:
try:
elements = next(iterator)
except StopIteration:
return
for sub_queue, element in zip(queues, elements):
sub_queue.append(element)
yield queue.popleft()
return tuple(map(coordinate, queues))
의 체크
>>> from itertools import count
>>> iterable = [count(), count()]
>>> result = transpose_finite_iterables(transpose_finite_iterable(iterable))
>>> result
(<generator object transpose_finite_iterables.<locals>.coordinate at ...>, <generator object transpose_finite_iterables.<locals>.coordinate at ...>)
>>> next(result[0])
0
>>> next(result[0])
1
합성
이제 우리는 우리 정의할 수 있는 일반적인 기능을 위해 작업 iterables 의 iterables 그 사람들은 유한하고 다른 사람은 잠재적으로 무한한 사용하는 functools.singledispatch
장식 아
from collections import (abc,
deque)
from functools import singledispatch
@singledispatch
def transpose(object_):
"""
Transposes given object.
"""
raise TypeError('Unsupported object type: {type}.'
.format(type=type))
@transpose.register(abc.Iterable)
def transpose_finite_iterables(object_):
"""
Transposes given iterable of finite iterables.
"""
iterator = iter(object_)
try:
first_elements = next(iterator)
except StopIteration:
return ()
queues = [deque([element])
for element in first_elements]
def coordinate(queue):
while True:
if not queue:
try:
elements = next(iterator)
except StopIteration:
return
for sub_queue, element in zip(queues, elements):
sub_queue.append(element)
yield queue.popleft()
return tuple(map(coordinate, queues))
def transpose_finite_iterable(object_):
"""
Transposes given finite iterable of iterables.
"""
yield from zip(*object_)
try:
transpose.register(abc.Collection, transpose_finite_iterable)
except AttributeError:
# Python3.5-
transpose.register(abc.Mapping, transpose_finite_iterable)
transpose.register(abc.Sequence, transpose_finite_iterable)
transpose.register(abc.Set, transpose_finite_iterable)
으로 간주 될 수있는 자신의 역(수학자들의 종류를 호출 기능 "involutions")클래스에서의 바이너리 사업자는 유한 비 빈 iterables.
보너스로의 singledispatch
ing 우리가 처리할 수 있는 numpy
배열음
import numpy as np
...
transpose.register(np.ndarray, np.transpose)
다음처럼 사용
>>> array = np.arange(4).reshape((2,2))
>>> array
array([[0, 1],
[2, 3]])
>>> transpose(array)
array([[0, 2],
[1, 3]])
참고
이 transpose
반환 반복기도와 경우는 사람을 원 tuple
의 list
s 다음과 같이 OP-이 만들 수 있습니다 또한 map
내장 기능 아
>>> original = [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
>>> tuple(map(list, transpose(original)))
(['a', 'b', 'c', 'd'], [1, 2, 3, 4])
광고
추가했 일반화 솔루션 lz
패키지 서 0.5.0
버전처럼 사용할 수 있습니다
>>> from lz.transposition import transpose
>>> list(map(tuple, transpose(zip(range(10), range(10, 20)))))
[(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), (10, 11, 12, 13, 14, 15, 16, 17, 18, 19)]
P.S.
해결책이 없다(적어도 분명한)처리하기 위한 잠재적으로 무한 반복 가능한 잠재적으로 무한한 iterables 지만,이 경우 보다 적게 일반적이지만.
이후 반환 튜플(사용할 수 있습니다 톤의 메모리) zip(*zipped)
속이는 것보다 더 똑똑 유용하다.
여기에는 함수하는 것이 실제로 당신의 역 zip.
def unzip(zipped):
"""Inverse of built-in zip function.
Args:
zipped: a list of tuples
Returns:
a tuple of lists
Example:
a = [1, 2, 3]
b = [4, 5, 6]
zipped = list(zip(a, b))
assert zipped == [(1, 4), (2, 5), (3, 6)]
unzipped = unzip(zipped)
assert unzipped == ([1, 2, 3], [4, 5, 6])
"""
unzipped = ()
if len(zipped) == 0:
return unzipped
dim = len(zipped[0])
for i in range(dim):
unzipped = unzipped + ([tup[i] for tup in zipped], )
return unzipped
original = [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
#unzip
a1 , a2 = zip(*original)
#make tuple with two list
result=(list(a1),list(a2))
result
result=(['a','b','c','d'], [1, 2, 3, 4])
을 고려하여 more_itertools.압축을 풉:
>>> from more_itertools import unzip
>>> original = [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
>>> [list(x) for x in unzip(original)]
[['a', 'b', 'c', 'd'], [1, 2, 3, 4]]
이전 답변 을 효율적으로 필요한 출력을 제공하는 의 튜플 목록, 보 목록의 튜플.이전에 대한 사용할 수 있습니다 tuple
가 map
.여기에서의 차이점은:
res1 = list(zip(*original)) # [('a', 'b', 'c', 'd'), (1, 2, 3, 4)]
res2 = tuple(map(list, zip(*original))) # (['a', 'b', 'c', 'd'], [1, 2, 3, 4])
또한,대부분의 이전 솔루션은 가정 Python2.7,가 zip
목록을 반환합니다기보다는 반복기입니다.
For Python3.x 해야 합니다 결과를 전달하는 기능 등 list
나 tuple
배기는 반복기입니다.메모리에 대한 효율적인 반복기를 생략할 수 있습니다 외부 list
고 tuple
전화를 위한 각각의 솔루션입니다.
동 zip(*seq)
은 매우 유용합니다,그것은 적합하지 않은 것일 수 있습에 대한 매우 오랜 시퀀스를 만드는 것이의 튜플 값을 전달됩니다.예를 들어,작업을했습니다와 좌표 시스템과 함께 백만이 넘는 항목을 찾을 signifcantly 빠르게 만들기 시퀀스를 직접 있습니다.
일반적인 접근 방법은 다음과 같이 될 것이다:
from collections import deque
seq = ((a1, b1, …), (a2, b2, …), …)
width = len(seq[0])
output = [deque(len(seq))] * width # preallocate memory
for element in seq:
for s, item in zip(output, element):
s.append(item)
하지만,무엇을 원하는가에 따라과 그 결과 선택의 컬렉션에 큰 차이를 만들 수 있습니다.에서 내 실제 사용하는 경우,집합을 사용하여 그 내부는 루프에 비해 현저히 더 빠르게 다른 모든 접근한다.
그리고,다른 사람들이 주목하는 경우 이와 데이터세트,그 의미가 있습니다 사용하 Numpy 또는 판 컬렉션을 대신 합니다.
이할 수 있는 방법을 바꾸어 2x4 튜플로 4x2tuple.
>>> tuple(zip(*[('a', 1), ('b', 2), ('c', 3), ('d', 4)]))
결과
[('a', 'b', 'c', 'd'), (1, 2, 3, 4)]