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

ดังนั้นคำถามของฉันคืออะไรคือวิธีที่ถูกต้องในการใช้การระบุความเข้าใจภายในรายการ?

คำตอบ:


166

ลองสิ่งนี้:

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

คุณต้องใส่i,jทูเพิลเพื่อให้ความเข้าใจรายการทำงานได้ หรืออีกวิธีหนึ่งที่ได้รับenumerate() แล้วส่งกลับ tuple คุณสามารถส่งคืนได้โดยตรงโดยไม่ต้องเอาออกมันเป็นครั้งแรก:

[pair for pair in enumerate(mylist)]

ไม่ว่าจะด้วยวิธีใดผลลัพธ์ที่ได้รับกลับเป็นไปตามที่คาดไว้:

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

4
ไม่บังคับให้เป็นทูเพิล นิพจน์ใด ๆ ที่ใช้ i และ j ที่ส่งกลับค่าจะทำ
Alvaro

การใช้การแจงนับเป็นสิ่งที่ดีวิธีการทำให้มีประสิทธิภาพมากขึ้นโดยใช้ itertools
Pramit

3
เพียงจำไว้ว่าทูเปิลถูกสร้างขึ้นโดย, ไม่ใช้(). ดังนั้น "การใส่i,jทูเพิล" จึงไม่สมเหตุสมผลเนื่องจากi,jมีทูเพิลอยู่แล้ว! ปัญหาคือตัวแยกวิเคราะห์ list comp ต้องการ parens สำหรับกลุ่มคำสั่ง
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']

ซึ่งไม่สอดคล้องกัน (IMHO) และสับสนกับไวยากรณ์ความเข้าใจในพจนานุกรม:

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

ตามที่ÓscarLópezระบุไว้คุณสามารถส่ง tuple แจกแจงได้โดยตรง:

>>> [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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.