İç liste anlayışını kullanan Python


125

Şöyle bir listem olduğunu varsayalım:

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

Değerleri indeksleriyle birlikte yazdırmak için Python'un bu enumeratefonksiyonunu kullanabilirim

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

Şimdi, onu bir içinde kullanmaya çalıştığımda list comprehensionbana bu hatayı veriyor

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

Öyleyse, sorum şu: listeyi anlamanın içinden numaralandırmanın doğru yolu nedir?

Yanıtlar:


166

Bunu dene:

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

i,jListe anlamanın işe yaraması için bir demet koymanız gerekir . Alternatif olarak, enumerate() zaten bir demet döndürdüğü için , önce paketini açmadan doğrudan iade edebilirsiniz:

[pair for pair in enumerate(mylist)]

Her iki durumda da, döndürülen sonuç beklendiği gibidir:

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

4
Tuple olmak zorunlu değil. İ ve j kullanan ve bir değer döndüren ifadeler işe
Alvaro

numaralandırma harika, itertools kullanarak onu daha verimli hale getirmeye ne dersiniz
Pramit

3
Sadece bir tanımlama grubu tarafından inşa edilmiştir unutmayın , değildir() . Bu yüzden " i,jbir demet içine koymak " anlamsızdır, çünkü i,jzaten bir demettir! Sorun, liste karşılaştırıcısının ifade grubu için ayrıştırıcılara ihtiyaç duymasıdır.
cowbert

46

Daha açık olmak gerekirse, bunun enumerateliste anlama söz dizimiyle hiçbir ilgisi yoktur .

Bu liste anlayışı bir demet listesi döndürür:

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

bu bir diktatör listesi:

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

liste listesi:

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

sözdizimi hatası:

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

Tutarsız (IMHO) ve sözlük anlayışları sözdizimi ile kafa karıştırıcı olan:

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

Ve bir dizi demet:

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

Óscar López'in belirttiği gibi, numaralandırma dizisini doğrudan geçebilirsiniz:

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

32

Veya bir liste anlama konusunda ısrarcı değilseniz:

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

12

Uzun listeler kullanıyorsanız, listeyi anlama daha hızlı görünür, daha okunaklı görünebilir.

~$ 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 Test etmedim ama bahse girerim [t for t in enumerate(my list)]daha da hızlıdır.
kurt

11

İşte bunu yapmanın bir yolu:

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

Alternatif olarak şunları yapabilirsiniz:

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

Bir hata almanızın nedeni, etrafındaki () işaretini kaçırmanız ive jonu bir demet haline getirmenizdi .



0

Hepsi harika cevaplar çocuklar. Buradaki sorunun numaralandırmaya özgü olduğunu biliyorum ama bunun gibi bir şey, sadece başka bir bakış açısı

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

Performans açısından birden fazla listeyi paralel olarak yinelemek gerekirse, daha güçlü hale gelir. Sadece bir düşünce

a = ["5", "6", "1", "2"]
b = ["a", "b", "c", "d"]
tupleList = list( izip( count(), a, b ) )
print(tupleList)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.