튜플 목록에서 첫 번째 요소를 얻는 방법은 무엇입니까?


178

아래에 첫 번째 요소가 id이고 다른 요소가 문자열 인 목록이 있습니다.

[(1, u'abc'), (2, u'def')]

다음과 같이이 튜플 목록에서만 ID 목록을 만들고 싶습니다.

[1,2]

이 목록을 사용 __in하므로 정수 값 목록이어야합니다.

답변:


245
>>> a = [(1, u'abc'), (2, u'def')]
>>> [i[0] for i in a]
[1, 2]

68

zip 기능을 사용하여 요소를 분리하십시오.

>>> inpt = [(1, u'abc'), (2, u'def')]
>>> unzipped = zip(*inpt)
>>> print unzipped
[(1, 2), (u'abc', u'def')]
>>> print list(unzipped[0])
[1, 2]

편집 (@BradSolomon) : 위는 Python 2.x에서 작동하며 여기서 zip목록을 반환합니다.

Python 3.x에서는 zip반복자를 반환하며 다음은 위와 같습니다.

>>> print(list(list(zip(*inpt))[0]))
[1, 2]

별도의 수입이 필요합니까?
Juliandot 너트

2
아니요, 내장 함수입니다. (Python 2.x에서)
WayneSan

22

이 같은 것을 의미합니까?

new_list = [ seq[0] for seq in yourlist ]

실제로 가지고있는 것은 tuple세트 목록이 아닌 객체 목록입니다 (원래 질문이 암시 한 것처럼). 실제로 세트 목록 인 경우 세트에 순서가 없기 때문에 첫 번째 요소 가 없습니다.

여기서는 일반적으로 1 요소 튜플 목록을 만드는 것보다 더 유용하기 때문에 플랫 목록을 만들었습니다. 그러나, 당신은 쉽게 바로 교체하여 1 개 요소 튜플의 목록을 만들 수 있습니다 seq[0](seq[0],).


나는 그것을 시도했다. 그것은이 오류를 제공합니다 :int() argument must be a string or a number, not 'QuerySet'
wasimbhalli

4
@wasimbhalli- int()내 솔루션에는 어디에도 없으므로 코드에서 나중에 예외가 발생해야합니다.
mgilson

질문을 업데이트했습니다. 나중에 __in데이터를 필터링 하기 위해이 목록을 사용해야 합니다.
wasimbhalli

무엇 __in입니까? -입력 한 예제 입력에 따라 정수 목록이 생성됩니다. 그러나 튜플 목록이 정수로 시작하지 않으면 정수를 얻지 않고을 통해 정수로 만들 int거나 첫 번째 요소를 정수로 변환 할 수없는 이유를 알아 내려고 시도해야합니다.
mgilson

합니까의 new_list = [ seq[0] for seq in yourlist if type(seq[0]) == int]작업?
pR0Ps 27. 12. 12.

11

"튜플 포장 풀기"를 사용할 수 있습니다.

>>> my_list = [(1, u'abc'), (2, u'def')]
>>> my_ids = [idx for idx, val in my_list]
>>> my_ids
[1, 2]

반복시 각 튜플의 압축이 풀리고 해당 값이 변수 idx및 로 설정됩니다 val.

>>> x = (1, u'abc')
>>> idx, val = x
>>> idx
1
>>> val
u'abc'

8

이것은 무엇 operator.itemgetter을위한 것입니다.

>>> a = [(1, u'abc'), (2, u'def')]
>>> import operator
>>> b = map(operator.itemgetter(0), a)
>>> b
[1, 2]

itemgetter문은 함수 반환 지정한 요소의 인덱스를 반환합니다. 글쓰기와 똑같습니다

>>> b = map(lambda x: x[0], a)

그러나 나는 그것이 itemgetter더 명확하고 더 명백 하다는 것을 안다 .

이것은 간단한 정렬 문장을 만드는 데 편리합니다. 예를 들어

>>> c = sorted(a, key=operator.itemgetter(0), reverse=True)
>>> c
[(2, u'def'), (1, u'abc')]

7

python3.X의 성능 관점에서

  • [i[0] for i in a]그리고 list(zip(*a))[0]동등하다
  • 그들은보다 빠르다 list(map(operator.itemgetter(0), a))

암호

import timeit


iterations = 100000
init_time = timeit.timeit('''a = [(i, u'abc') for i in range(1000)]''', number=iterations)/iterations
print(timeit.timeit('''a = [(i, u'abc') for i in range(1000)]\nb = [i[0] for i in a]''', number=iterations)/iterations - init_time)
print(timeit.timeit('''a = [(i, u'abc') for i in range(1000)]\nb = list(zip(*a))[0]''', number=iterations)/iterations - init_time)

산출

3.491014136001468e-05

3.422205176000717e-05


6

튜플이 고유하면 작동 할 수 있습니다

>>> a = [(1, u'abc'), (2, u'def')]
>>> a
[(1, u'abc'), (2, u'def')]
>>> dict(a).keys()
[1, 2]
>>> dict(a).values()
[u'abc', u'def']
>>> 

4
주문이 취소됩니다. ordereddict그래도 작동 할 수 있습니다 .
Tim Tisdall

2 개 이상의 튜플이 솔루션과 동일한 첫 번째 요소를
가지면

3

내가 달릴 때 (위의 제안대로) :

>>> a = [(1, u'abc'), (2, u'def')]
>>> import operator
>>> b = map(operator.itemgetter(0), a)
>>> b

돌아 오는 대신 :

[1, 2]

나는 이것을 반환으로 받았다 :

<map at 0xb387eb8>

list ()를 사용해야한다는 것을 알았습니다.

>>> b = list(map(operator.itemgetter(0), a))

이 제안을 사용하여 목록을 성공적으로 반환하십시오. 즉,이 솔루션에 만족합니다. 감사합니다. (Spyder, iPython 콘솔, Python v3.6을 사용하여 테스트 / 실행)


3

다른 접근법의 런타임을 비교하는 것이 유용 할 수 있다고 생각했기 때문에 ( simple_benchmark 라이브러리를 사용하여 ) 벤치 마크를 만들었습니다.

I) 요소가 2 개인 튜플이있는 벤치 마크 여기에 이미지 설명을 입력하십시오

인덱스로 튜플에서 첫 번째 요소를 선택할 것으로 예상 할 수 있듯이 0정확히 2 개의 값을 기대하여 포장 풀기 솔루션과 가장 가까운 솔루션입니다.

import operator
import random

from simple_benchmark import BenchmarkBuilder

b = BenchmarkBuilder()



@b.add_function()
def rakesh_by_index(l):
    return [i[0] for i in l]


@b.add_function()
def wayneSan_zip(l):
    return list(list(zip(*l))[0])


@b.add_function()
def bcattle_itemgetter(l):
     return list(map(operator.itemgetter(0), l))


@b.add_function()
def ssoler_upacking(l):
    return [idx for idx, val in l]

@b.add_function()
def kederrack_unpacking(l):
    return [f for f, *_ in l]



@b.add_arguments('Number of tuples')
def argument_provider():
    for exp in range(2, 21):
        size = 2**exp
        yield size, [(random.choice(range(100)), random.choice(range(100))) for _ in range(size)]


r = b.run()
r.plot()

II) 2 개 이상의 요소가있는 튜플이있는 벤치 마크 여기에 이미지 설명을 입력하십시오

import operator
import random

from simple_benchmark import BenchmarkBuilder

b = BenchmarkBuilder()

@b.add_function()
def kederrack_unpacking(l):
    return [f for f, *_ in l]


@b.add_function()
def rakesh_by_index(l):
    return [i[0] for i in l]


@b.add_function()
def wayneSan_zip(l):
    return list(list(zip(*l))[0])


@b.add_function()
def bcattle_itemgetter(l):
     return list(map(operator.itemgetter(0), l))


@b.add_arguments('Number of tuples')
def argument_provider():
    for exp in range(2, 21):
        size = 2**exp
        yield size, [tuple(random.choice(range(100)) for _
                     in range(random.choice(range(2, 100)))) for _ in range(size)]

from pylab import rcParams
rcParams['figure.figsize'] = 12, 7

r = b.run()
r.plot()

0

그것들은 세트가 아닌 튜플입니다. 당신은 이것을 할 수 있습니다 :

l1 = [(1, u'abc'), (2, u'def')]
l2 = [(tup[0],) for tup in l1]
l2
>>> [(1,), (2,)]

2
실제로 무엇을 요구 하느냐
Mad Physicist

0

튜플을 풀고 목록 이해를 사용하여 첫 번째 요소 만 가져올 수 있습니다 .

l = [(1, u'abc'), (2, u'def')]
[f for f, *_ in l]

산출:

[1, 2]

이것은 튜플에있는 요소 수에 관계없이 작동합니다.

l = [(1, u'abc'), (2, u'def', 2, 4, 5, 6, 7)]
[f for f, *_ in l]

산출:

[1, 2]

0

아무도 numpy를 사용하도록 제안한 이유가 무엇인지 궁금했지만 지금은 확인 후 이해합니다. 혼합 유형 배열에는 적합하지 않을 수 있습니다.

이것은 numpy의 해결책 일 것입니다 :

>>> import numpy as np

>>> a = np.asarray([(1, u'abc'), (2, u'def')])
>>> a[:, 0].astype(int).tolist()
[1, 2]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.