Python, использующий перечисление внутри понимания списка


125

Предположим, у меня есть такой список:

mylist = ["a","b","c","d"]

Чтобы напечатать значения вместе с их индексом, я могу использовать enumerateфункцию Python, подобную этой

>>> for i,j in enumerate(mylist):
...     print i,j
...
0 a
1 b
2 c
3 d
>>>

Теперь, когда я пытаюсь использовать его внутри, list comprehensionон дает мне эту ошибку

>>> [i,j for i,j in enumerate(mylist)]
  File "<stdin>", line 1
    [i,j for i,j in enumerate(mylist)]
           ^
SyntaxError: invalid syntax

Итак, мой вопрос: как правильно использовать enumerate внутри списка?

Ответы:


166

Попробуй это:

[(i, j) for i, j in enumerate(mylist)]

Вам нужно поместить i,jвнутрь кортежа, чтобы понимание списка работало. В качестве альтернативы, учитывая, что он enumerate() уже возвращает кортеж, вы можете вернуть его напрямую, не распаковывая его:

[pair for pair in enumerate(mylist)]

В любом случае результат будет таким, как ожидалось:

> [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

4
Не обязательно быть кортежем. Подойдет любое выражение, использующее i и j, которое возвращает значение
Альваро

использование перечисления замечательно, как насчет того, чтобы сделать его более эффективным с помощью itertools
Прамит

3
Просто помните , что кортеж , построенный , не() . Таким образом, "помещать i,jв кортеж" не имеет смысла, поскольку i,jэто уже кортеж! Проблема в том, что синтаксическому анализатору списка нужны скобки для группы операторов.
Cowbert

46

Чтобы быть действительно ясным, это не имеет ничего общего enumerateи полностью связано с синтаксисом понимания списка.

Это понимание списка возвращает список кортежей:

[(i,j) for i in range(3) for j in 'abc']

это список изречений:

[{i:j} for i in range(3) for j in 'abc']

список списков:

[[i,j] for i in range(3) for j in 'abc']

синтаксическая ошибка:

[i,j for i in range(3) for j in 'abc']

Что непоследовательно (ИМХО) и сбивает с толку синтаксис словаря:

>>> {i:j for i,j in enumerate('abcdef')}
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f'}

И набор кортежей:

>>> {(i,j) for i,j in enumerate('abcdef')}
set([(0, 'a'), (4, 'e'), (1, 'b'), (2, 'c'), (5, 'f'), (3, 'd')])

Как заявил Оскар Лопес, вы можете просто передать кортеж перечисления напрямую:

>>> [t for t in enumerate('abcdef') ] 
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f')]

32

Или, если вы не настаиваете на использовании списка:

>>> mylist = ["a","b","c","d"]
>>> list(enumerate(mylist))
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

12

Если вы используете длинные списки, кажется, что их понимание происходит быстрее, не говоря уже о более удобочитаемом.

~$ python -mtimeit -s"mylist = ['a','b','c','d']" "list(enumerate(mylist))"
1000000 loops, best of 3: 1.61 usec per loop
~$ python -mtimeit -s"mylist = ['a','b','c','d']" "[(i, j) for i, j in enumerate(mylist)]"
1000000 loops, best of 3: 0.978 usec per loop
~$ python -mtimeit -s"mylist = ['a','b','c','d']" "[t for t in enumerate(mylist)]"
1000000 loops, best of 3: 0.767 usec per loop

2
+1 Не тестировал, но ставлю [t for t in enumerate(my list)]еще быстрее.
волк

11

Вот как это сделать:

>>> mylist = ['a', 'b', 'c', 'd']
>>> [item for item in enumerate(mylist)]
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

В качестве альтернативы вы можете:

>>> [(i, j) for i, j in enumerate(mylist)]
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

Причина, по которой вы получили ошибку, заключалась в том, что вам не хватало () iи вы jсделали его кортежем.



0

Всем отличный ответ, ребята. Я знаю, что вопрос здесь относится к перечислению, но как насчет чего-то вроде этого, просто другой точки зрения

from itertools import izip, count
a = ["5", "6", "1", "2"]
tupleList = list( izip( count(), a ) )
print(tupleList)

Он становится более мощным, если нужно перебирать несколько списков параллельно с точки зрения производительности. Просто мысль

a = ["5", "6", "1", "2"]
b = ["a", "b", "c", "d"]
tupleList = list( izip( count(), a, b ) )
print(tupleList)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.