2013-02-26 3 views
9

Итак, у меня есть x=[(12,), (1,), (3,)] (список кортежей), и я хочу x=[12, 1, 3] (список целых чисел) наилучшим образом? Не могли бы вы помочь?Список кортежей Python в список int

+3

Измените свой вопрос, чтобы включить попытку решения. Спасибо. – bernie

+0

Ваши кортежи всегда одинаковой формы? '(n,)'? –

+1

Альтернативный 'zip (* x) [0]' или 'next (zip (* x))' на Py3k – JBernardo

ответ

5
y = [i[0] for i in x] 

Это работает только для одного элемента на каждый кортеж.

Однако, если у вас есть несколько элементов на кортеж, вы можете использовать несколько более сложный список понимание:

y = [i[j] for i in x for j in range(len(i))] 

Ссылка: List Comprehensions

+1

@pedro - Да, он всегда будет иметь один элемент. – NullException

+0

Для второго: если вам нужно сгладить последовательность последовательностей, есть рецепт в документах '' itertools' '(http://docs.python.org/2/library/itertools.html#recipes), называемых ' flatten'. Вероятно, стоит понять и это, и понимание списка. – abarnert

+1

Разве вы не должны инвертировать порядок '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' – phant0m

2

Просто сделай это:

x = [i[0] for i in x] 

Объяснение :

>>> x=[(12,), (1,), (3,)] 

>>> x 
[(12,), (1,), (3,)] 

>>> [i for i in x] 
[(12,), (1,), (3,)] 

>>> [i[0] for i in x] 
[12, 1, 3] 
1

Это самый эффективный способ:

x = [i for i, in x] 

или, что то же самое

x = [i for (i,) in x] 

Это немного медленнее:

x = [i[0] for i in x] 
+0

Вы уверены, что разница в эффективности? В быстром тесте с 1М-элементом 'list' в 3.3.0 они взяли 4.15ms и 4.14ms соответственно - и это выглядит больше, чем 4 мс, это было время, затрачиваемое на повторение списка и создание нового списка, так что ничего скорее всего, будет быстрее. Если вы измените x на ген xp и замените два listcomps геном xp, поданным на 'deque (genexp, maxlen = 0)', я получаю 1.36us против 1.32us. – abarnert

+0

Что еще более важно, какой сценарий вы представляете, где кому-то будет интересно, какая из этих двух более эффективна? – abarnert

+1

Где эта тенденция эффективности для Python на SO, исходящая из любой точки? Для меня это похоже на трюк, чтобы набрать больше очков. – phant0m

0

вы можете использовать функцию карты ....

map(lambda y: y[0], x) 
+2

Если вы собираетесь использовать 'map', вы можете использовать' itemgetter' вместо 'lambda'. – abarnert

11

Вы не сказали, что вы имеете в виду под «лучшим», но предположительно вы имеете в виду «большинство питонов» или «наиболее читаемых» или что-то в этом роде.

Понимание списка, данное F3AR3DLEGEND, возможно, является самым простым. Любой, кто знает, как читать понимание списка, сразу узнает, что это значит.

y = [i[0] for i in x] 

Однако часто вам не нужен список, просто то, что можно повторить один раз. Если у вас есть миллиард элементов в x, построив миллиард-элемент y, чтобы перебирать его по одному элементу за раз, может быть плохой идеей. Таким образом, вы можете использовать выражение генератора:

y = (i[0] for i in x) 

Если вы предпочитаете функциональное программирование, вы можете предпочесть использовать map. Недостатком map является то, что вы должны передать его функции, а не просто выражение, которое означает, что вам необходимо либо использовать lambda функцию или itemgetter:

y = map(operator.itemgetter(0), x) 

В Python 3, это эквивалентно генератору выражение; если вы хотите list, перейдите к list. В Python 2 он возвращает list; если вы хотите итератор, используйте itertools.imap вместо map.

Если вы хотите получить более общее решение уплощения, вы можете написать его самостоятельно, но это всегда стоит смотреть на itertools для общих решений такого рода, и есть на самом деле рецепт называется flatten, который используется для «Свести один уровень вложенности».Так, копировать и вставлять, что в ваш код (или pip install more-itertools), и вы можете просто сделать это:

y = flatten(x) 

Если посмотреть на то, как flatten реализован, а затем, как chain.from_iterable реализуется, а затем, как chain является вы заметите, что вы можете написать одно и то же с точки зрения встроенных функций. Но зачем беспокоиться, когда flatten будет более читабельным и очевидным?

Наконец, если вы хотите, чтобы уменьшить общую версию для вложенного списка понимания (или выражение генератора, конечно):

y = [j for i in x for j in i] 

Однако вложенные списочные очень легко ошибиться, как в письменной форме и чтение. (Обратите внимание, что F3AR3DLEGEND, тот же самый человек, который дал самый простой ответ первым, также дал вложенное понимание и понял, что это неправильно. Если он не может это сделать, вы уверены, что хотите попробовать?) Для действительно простых случаев, Re не так уж плохо, но все же, я думаю, что flatten намного легче читать.

+0

Итак, что вы думаете о том, что пакет распаковки à la pattern соответствует? –

+0

@PavelAnossov: Как насчет этого? Когда вы хотите распаковать кортеж на отдельные именованные переменные, это, безусловно, точно. Когда у вас есть кортеж одного, который вы просто хотите превратить в одно значение, это выглядит не совсем ясно, но это не вызывает возражений. – abarnert