문제

나의 목록을 가지고 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 다시 돌아가려면의 구조를 원 iterableresult 무한 반복 가능한 유한 iterables(tuples 에서 우리의 경우):

>>> 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.


보너스로의 singledispatching 우리가 처리할 수 있는 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 반환 반복기도와 경우는 사람을 원 tuplelists 다음과 같이 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]]     

이전 답변 을 효율적으로 필요한 출력을 제공하는 의 튜플 목록, 보 목록의 튜플.이전에 대한 사용할 수 있습니다 tuplemap.여기에서의 차이점은:

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 해야 합니다 결과를 전달하는 기능 등 listtuple 배기는 반복기입니다.메모리에 대한 효율적인 반복기를 생략할 수 있습니다 외부 listtuple 전화를 위한 각각의 솔루션입니다.

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)]
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top