Итак, у меня есть x=[(12,), (1,), (3,)]
(список кортежей), и я хочу x=[12, 1, 3]
(список целых чисел) наилучшим образом? Не могли бы вы помочь?Список кортежей Python в список int
ответ
y = [i[0] for i in x]
Это работает только для одного элемента на каждый кортеж.
Однако, если у вас есть несколько элементов на кортеж, вы можете использовать несколько более сложный список понимание:
y = [i[j] for i in x for j in range(len(i))]
Ссылка: List Comprehensions
@pedro - Да, он всегда будет иметь один элемент. – NullException
Для второго: если вам нужно сгладить последовательность последовательностей, есть рецепт в документах '' itertools' '(http://docs.python.org/2/library/itertools.html#recipes), называемых ' flatten'. Вероятно, стоит понять и это, и понимание списка. – abarnert
Разве вы не должны инвертировать порядок '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' – phant0m
Просто сделай это:
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]
Это самый эффективный способ:
x = [i for i, in x]
или, что то же самое
x = [i for (i,) in x]
Это немного медленнее:
x = [i[0] for i in x]
Вы уверены, что разница в эффективности? В быстром тесте с 1М-элементом 'list' в 3.3.0 они взяли 4.15ms и 4.14ms соответственно - и это выглядит больше, чем 4 мс, это было время, затрачиваемое на повторение списка и создание нового списка, так что ничего скорее всего, будет быстрее. Если вы измените x на ген xp и замените два listcomps геном xp, поданным на 'deque (genexp, maxlen = 0)', я получаю 1.36us против 1.32us. – abarnert
Что еще более важно, какой сценарий вы представляете, где кому-то будет интересно, какая из этих двух более эффективна? – abarnert
Где эта тенденция эффективности для Python на SO, исходящая из любой точки? Для меня это похоже на трюк, чтобы набрать больше очков. – phant0m
вы можете использовать функцию карты ....
map(lambda y: y[0], x)
Если вы собираетесь использовать 'map', вы можете использовать' itemgetter' вместо 'lambda'. – abarnert
Вы не сказали, что вы имеете в виду под «лучшим», но предположительно вы имеете в виду «большинство питонов» или «наиболее читаемых» или что-то в этом роде.
Понимание списка, данное 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
намного легче читать.
Итак, что вы думаете о том, что пакет распаковки à la pattern соответствует? –
@PavelAnossov: Как насчет этого? Когда вы хотите распаковать кортеж на отдельные именованные переменные, это, безусловно, точно. Когда у вас есть кортеж одного, который вы просто хотите превратить в одно значение, это выглядит не совсем ясно, но это не вызывает возражений. – abarnert
Измените свой вопрос, чтобы включить попытку решения. Спасибо. – bernie
Ваши кортежи всегда одинаковой формы? '(n,)'? –
Альтернативный 'zip (* x) [0]' или 'next (zip (* x))' на Py3k – JBernardo