enumerate () หมายถึงอะไร


คำตอบ:


513

enumerate()ฟังก์ชั่นเพิ่มเคาน์เตอร์ไปยัง iterable

ดังนั้นสำหรับแต่ละองค์ประกอบในcursortuple ผลิตด้วย(counter, element); forผูกห่วงที่row_numberและrowตามลำดับ

การสาธิต:

>>> elements = ('foo', 'bar', 'baz')
>>> for elem in elements:
...     print elem
... 
foo
bar
baz
>>> for count, elem in enumerate(elements):
...     print count, elem
... 
0 foo
1 bar
2 baz

ตามค่าเริ่มต้นenumerate()เริ่มนับที่0แต่ถ้าคุณให้อาร์กิวเมนต์จำนวนเต็มตัวที่สองมันจะเริ่มจากจำนวนนั้นแทน:

>>> for count, elem in enumerate(elements, 42):
...     print count, elem
... 
42 foo
43 bar
44 baz

หากคุณต้องนำไปใช้ใหม่enumerate()ใน Python ต่อไปนี้เป็นสองวิธีในการบรรลุเป้าหมายดังกล่าว คนหนึ่งใช้itertools.count()ในการนับอีกคนหนึ่งนับด้วยตนเองในฟังก์ชั่นเครื่องกำเนิด :

from itertools import count

def enumerate(it, start=0):
    # return an iterator that adds a counter to each element of it
    return zip(count(start), it)

และ

def enumerate(it, start=0):
    count = start
    for elem in it:
        yield (count, elem)
        count += 1

การใช้งานจริงใน Cใกล้เคียงกับหลังด้วยการปรับให้เหมาะสมเพื่อนำวัตถุ tuple เดียวสำหรับfor i, ...กรณีการนำออกจากกล่องทั่วไปและใช้ค่าจำนวนเต็ม C มาตรฐานสำหรับตัวนับจนกว่าตัวนับจะใหญ่เกินไปเพื่อหลีกเลี่ยงการใช้วัตถุจำนวนเต็ม Python มากมาย)


92

มันเป็นฟังก์ชันในตัวที่ส่งคืนวัตถุที่สามารถทำซ้ำได้ ดูเอกสาร

กล่าวโดยย่อก็คือลูปขององค์ประกอบของ iterable (เช่นรายการ) เช่นเดียวกับหมายเลขดัชนีรวมอยู่ใน tuple:

for item in enumerate(["a", "b", "c"]):
    print item

พิมพ์

(0, "a")
(1, "b")
(2, "c")

มันจะมีประโยชน์ถ้าคุณต้องการวนลูปมากกว่าลำดับ (หรือสิ่งอื่น ๆ ที่ทำซ้ำได้) และต้องการให้มีตัวนับดัชนี ถ้าคุณต้องการที่เคาน์เตอร์ที่จะเริ่มต้นจากบางส่วนค่าอื่น (ปกติ 1) enumerateคุณสามารถให้ว่าเป็นอาร์กิวเมนต์ที่สองที่จะ


1
หากคุณเพิ่มตัวแปรตัวที่สองลงไปitemคุณสามารถลบวงเล็บได้: D
Abdelouahab

2
Pedantic: เป็นฟังก์ชันที่ส่งคืนตัววนซ้ำไม่ใช่ตัวกำเนิด เครื่องกำเนิดไฟฟ้าเป็นคลาสเฉพาะของฟังก์ชั่นที่ผู้ใช้กำหนด (การใช้yield/ yield fromหรือการแสดงออกของเครื่องกำเนิดซึ่งโดยปริยายyield); enumerateไม่ใช่เครื่องกำเนิดไฟฟ้า สำหรับวัตถุประสงค์ที่เกี่ยวข้องทั้งหมดเป็ดพิมพ์ไม่มีความแตกต่าง แต่การตรวจสอบชนิดที่ชัดเจนและเอกสารภาษา Python สามารถใช้คำว่า "กำเนิด" enumerateสำหรับวัตถุประสงค์หนึ่งซึ่งไม่ครอบคลุม
ShadowRanger

22

ฉันกำลังอ่านหนังสือ ( Effective Python ) โดย Brett Slatkin และเขาแสดงวิธีอื่นในการทำซ้ำในรายการและรู้ดัชนีของรายการปัจจุบันในรายการแต่เขาแนะนำว่าจะไม่ควรใช้และใช้enumerateแทน ฉันรู้ว่าคุณถามความหมายของการแจกแจง แต่เมื่อฉันเข้าใจสิ่งต่อไปนี้ฉันยังเข้าใจด้วยว่าการenumerateวนซ้ำรายการในขณะที่รู้ว่าดัชนีของรายการปัจจุบันง่ายขึ้น (และอ่านได้มากขึ้น)

list_of_letters = ['a', 'b', 'c']
for i in range(len(list_of_letters)):
    letter = list_of_letters[i]
    print (i, letter)

ผลลัพธ์คือ:

0 a
1 b
2 c

ฉันยังเคยทำบางสิ่งบางอย่างแม้แต่ sillier ก่อนที่ฉันจะอ่านเกี่ยวกับenumerateฟังก์ชั่น

i = 0
for n in list_of_letters:
    print (i, n)
    i += 1

มันสร้างผลลัพธ์เดียวกัน

แต่enumerateฉันต้องเขียนด้วย:

list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
    print (i, letter)

20

ดังที่ผู้ใช้รายอื่นได้กล่าวถึงenumerateคือตัวสร้างที่เพิ่มดัชนีส่วนเพิ่มถัดจากแต่ละรายการของ iterable

ดังนั้นถ้าคุณมีการพูดรายการl = ["test_1", "test_2", "test_3"]ที่จะทำให้คุณมีบางสิ่งบางอย่างเช่นนี้list(enumerate(l))[(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]

ตอนนี้เมื่อมีประโยชน์ กรณีการใช้งานที่เป็นไปได้คือเมื่อคุณต้องการวนซ้ำไอเท็มและคุณต้องการข้ามไอเท็มเฉพาะที่คุณรู้เฉพาะดัชนีของมันในรายการ แต่ไม่ใช่ค่าของมัน (เนื่องจากไม่รู้จักค่าในเวลานั้น)

for index, value in enumerate(joint_values):
   if index == 3:
       continue

   # Do something with the other `value`

ดังนั้นโค้ดของคุณจะอ่านได้ดีขึ้นเพราะคุณสามารถทำลูปปกติด้วยrangeเพื่อเข้าถึงไอเท็มที่คุณต้องการสร้างดัชนี (เช่นjoint_values[i])

แม้ว่าผู้ใช้รายอื่นพูดถึงการenumerateใช้zipงานฉันคิดว่าวิธีที่บริสุทธิ์กว่า (แต่ซับซ้อนกว่าเล็กน้อย) โดยไม่ใช้itertoolsมีดังต่อไปนี้:

def enumerate(l, start=0):
    return zip(range(start, len(l) + start), l)

ตัวอย่าง:

l = ["test_1", "test_2", "test_3"]
enumerate(l)
enumerate(l, 10)

เอาท์พุท:

[(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]

[(10, 'test_1'), (11, 'test_2'), (12, 'test_3')]

ตามที่ระบุไว้ในความคิดเห็นวิธีการที่มีช่วงนี้จะไม่ทำงานกับ iterables โดยพลการเช่นเดียวกับenumerateฟังก์ชั่นเดิมไม่


เหตุผลที่คำตอบอื่น ๆ กล่าวถึงitertoolsคือrangeแนวทางของคุณใช้ได้กับตู้สินค้าเท่านั้น enumerateทำงานร่วมกับ iterables โดยพลการ; ถ้าคุณต้องการวนไฟล์for lineno, line in enumerate(myfile):ทำงานได้ แต่คุณทำไม่ได้range(len(myfile))เพราะไม่ทราบความยาวจนกว่าจะถึง EOF
ShadowRanger

12

ฟังก์ชันแจกแจงทำงานดังนี้:

doc = """I like movie. But I don't like the cast. The story is very nice"""
doc1 = doc.split('.')
for i in enumerate(doc1):
     print(i)

ผลลัพธ์คือ

(0, 'I like movie')
(1, " But I don't like the cast")
(2, ' The story is very nice')
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.