Enum Cả () có nghĩa là gì?


Câu trả lời:


513

Các enumerate()chức năng bổ sung thêm một bộ đếm đến một iterable.

Vì vậy, đối với mỗi phần tử trong cursor, một tuple được tạo ra với (counter, element); các forvới phím tắt vòng lặp đó để row_numberrow, tương ứng.

Bản giới thiệu:

>>> 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

Theo mặc định, enumerate()bắt đầu đếm tại 0nhưng nếu bạn cung cấp cho nó một đối số nguyên thứ hai, nó sẽ bắt đầu từ số đó:

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

Nếu bạn đã triển khai lại enumerate()trong Python, đây là hai cách để đạt được điều đó; một cái dùng itertools.count()để thực hiện đếm, cái còn lại đếm thủ công trong hàm tạo :

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

Việc triển khai thực tế trong C gần với phần sau hơn, với việc tối ưu hóa để sử dụng lại một đối tượng tuple duy nhất cho for i, ...trường hợp giải nén chung và sử dụng giá trị số nguyên C tiêu chuẩn cho bộ đếm cho đến khi bộ đếm trở nên quá lớn để tránh sử dụng đối tượng số nguyên Python (đó là không giới hạn).


92

Đó là một hàm dựng sẵn trả về một đối tượng có thể lặp đi lặp lại. Xem tài liệu .

Nói tóm lại, nó lặp lại các yếu tố của một lần lặp (như danh sách), cũng như số chỉ mục, được kết hợp trong một tuple:

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

in

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

Thật hữu ích nếu bạn muốn lặp qua một chuỗi (hoặc điều lặp lại khác) và cũng muốn có sẵn một bộ đếm chỉ mục. Nếu bạn muốn bộ đếm bắt đầu từ một số giá trị khác (thường là 1), bạn có thể đưa nó làm đối số thứ hai cho enumerate.


1
nếu bạn thêm một biến thứ hai vào itemthì bạn có thể xóa dấu ngoặc đơn: D
Abdelouahab

2
Pedantic: Đó là một hàm trả về một trình vòng lặp, không phải là một trình tạo. Trình tạo là một lớp cụ thể của các hàm do người dùng định nghĩa (sử dụng yield/ yield fromhoặc biểu thức trình tạo, ngầm định yield); enumeratekhông phải là một máy phát điện. Đối với tất cả các mục đích liên quan đến gõ vịt, không có sự khác biệt, nhưng kiểm tra loại rõ ràng và tài liệu ngôn ngữ Python chỉ sử dụng thuật ngữ "trình tạo" cho một mục đích, không bao gồm enumerate.
ShadowRanger

22

Tôi đang đọc một cuốn sách ( Python hiệu quả ) của Brett Slatkin và anh ấy chỉ ra một cách khác để lặp lại một danh sách và cũng biết chỉ số của mục hiện tại trong danh sách nhưng anh ấy khuyên rằng tốt hơn là không nên sử dụng nó và sử dụng enumeratethay thế. Tôi biết bạn đã hỏi liệt kê nghĩa là gì, nhưng khi tôi hiểu những điều sau đây, tôi cũng hiểu làm thế nào để enumeratelặp lại danh sách trong khi biết chỉ số của mục hiện tại dễ dàng hơn (và dễ đọc hơn).

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

Đầu ra là:

0 a
1 b
2 c

Tôi cũng đã từng làm một cái gì đó, thậm chí là sillier trước khi tôi đọc về enumeratechức năng.

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

Nó tạo ra cùng một đầu ra.

Nhưng với enumeratetôi chỉ cần viết:

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

20

Như những người dùng khác đã đề cập, enumeratelà một trình tạo thêm chỉ số gia tăng bên cạnh mỗi mục của một lần lặp.

Vì vậy, nếu bạn có một danh sách nói l = ["test_1", "test_2", "test_3"], list(enumerate(l))sẽ cung cấp cho bạn một cái gì đó như thế này : [(0, 'test_1'), (1, 'test_2'), (2, 'test_3')].

Bây giờ, khi điều này là hữu ích? Trường hợp sử dụng có thể là khi bạn muốn lặp lại các mục và bạn muốn bỏ qua một mục cụ thể mà bạn chỉ biết chỉ mục của nó trong danh sách chứ không phải giá trị của nó (vì lúc đó giá trị của nó không được biết).

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

   # Do something with the other `value`

Vì vậy, mã của bạn đọc tốt hơn bởi vì bạn cũng có thể thực hiện một vòng lặp thông thường rangenhưng sau đó để truy cập vào các mục bạn cần lập chỉ mục cho chúng (ví dụ, joint_values[i]).

Mặc dù một người dùng khác đã đề cập đến việc triển khai enumeratesử dụng zip, tôi nghĩ rằng một cách thuần túy hơn (nhưng phức tạp hơn một chút) mà không sử dụng itertoolslà như sau:

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

Thí dụ:

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

Đầu ra:

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

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

Như đã đề cập trong các ý kiến, cách tiếp cận với phạm vi này sẽ không hoạt động với các lần lặp tùy ý như enumeratechức năng ban đầu .


Lý do câu trả lời khác đề cập itertoolsrangecách tiếp cận của bạn chỉ hoạt động với các container. enumeratelàm việc với các vòng lặp tùy ý; nếu bạn muốn lặp lại một tệp, sẽ for lineno, line in enumerate(myfile):hoạt động, nhưng bạn không thể làm được range(len(myfile))vì độ dài không được biết cho đến khi bạn đạt EOF.
ShadowRanger

12

Hàm liệt kê hoạt động như sau:

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)

Đầu ra là

(0, 'I like movie')
(1, " But I don't like the cast")
(2, ' The story is very nice')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.