Как получить первый элемент в списке кортежей?

У меня есть список, как показано ниже, где первый элемент является идентификатором, а другой является строкой:

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

Я хочу создать список идентификаторов только из этого списка кортежей, как показано ниже:

[1,2]

Я буду использовать этот список в __in поэтому он должен быть списком целочисленных значений.

Ответ 1

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

Ответ 2

Используйте функцию 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]

Edit (@BradSolomon): вышеописанное работает для Python 2.x, где zip возвращает список.

В Python 3.x zip возвращает итератор, а следующее эквивалентно приведенному выше:

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

Ответ 3

Вы имеете в виду что-то вроде этого?

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

На самом деле у вас есть список объектов tuple, а не список наборов (как предполагал ваш оригинальный вопрос). Если на самом деле это список наборов, то нет первого элемента, потому что наборы не имеют порядка.

Здесь я создал плоский список, потому что обычно это кажется более полезным, чем создание списка из 1 элемента кортежей. Однако вы можете легко создать список из 1 элемента кортежей, просто заменив seq[0] на (seq[0],).

Ответ 4

Вы можете использовать "распаковку кортежа":

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

Ответ 5

Для этого и нужен 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')]

Ответ 6

С точки зрения производительности, в python3.X

  • [i[0] for я 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

Ответ 7

если кортежи уникальны, тогда это может работать

>>> 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']
>>> 

Ответ 8

когда я бежал (как было предложено выше):

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

Ответ 9

Это кортежи, а не набор. Вы можете сделать это:

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