Làm gì for row_number, row in enumerate(cursor):
trong Python?
Điều này enumerate
có nghĩa gì trong bối cảnh này?
Làm gì for row_number, row in enumerate(cursor):
trong Python?
Điều này enumerate
có nghĩa gì trong bối cảnh này?
Câu trả lời:
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 for
với phím tắt vòng lặp đó để row_number
và row
, 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 0
như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)
và
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).
Đó 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
.
item
thì bạn có thể xóa dấu ngoặc đơn: D
yield
/ yield from
hoặc biểu thức trình tạo, ngầm định yield
); enumerate
khô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
.
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 enumerate
thay 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 để enumerate
lặ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ề enumerate
chứ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 enumerate
tôi chỉ cần viết:
list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
print (i, letter)
Như những người dùng khác đã đề cập, enumerate
là 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 range
như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 enumerate
sử 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 itertools
là 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ư enumerate
chức năng ban đầu .
itertools
là range
cách tiếp cận của bạn chỉ hoạt động với các container. enumerate
là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.
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')