O que for row_number, row in enumerate(cursor):
faz no Python?
O que enumerate
significa neste contexto?
O que for row_number, row in enumerate(cursor):
faz no Python?
O que enumerate
significa neste contexto?
Respostas:
A enumerate()
função adiciona um contador a um iterável.
Portanto, para cada elemento em cursor
, uma tupla é produzida com (counter, element)
; o for
loop vincula isso a row_number
e row
, respectivamente.
Demo:
>>> 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
Por padrão, enumerate()
começa a contar, 0
mas se você der um segundo argumento inteiro, ele começará a partir desse número:
>>> for count, elem in enumerate(elements, 42):
... print count, elem
...
42 foo
43 bar
44 baz
Se você fosse reimplementar enumerate()
no Python, aqui estão duas maneiras de conseguir isso; um usando itertools.count()
para fazer a contagem, o outro contando manualmente em uma função de gerador :
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)
e
def enumerate(it, start=0):
count = start
for elem in it:
yield (count, elem)
count += 1
A implementação real em C é mais próxima da última, com otimizações para reutilizar um único objeto de tupla para o for i, ...
caso de descompactação comum e usando um valor inteiro C padrão para o contador até que o contador se torne muito grande para evitar o uso de um objeto inteiro Python (que é ilimitado).
É uma função interna que retorna um objeto que pode ser repetido. Veja a documentação .
Em resumo, faz um loop sobre os elementos de um iterável (como uma lista), bem como um número de índice, combinado em uma tupla:
for item in enumerate(["a", "b", "c"]):
print item
impressões
(0, "a")
(1, "b")
(2, "c")
É útil se você deseja fazer um loop sobre uma sequência (ou outra coisa iterável) e também deseja ter um contador de índice disponível. Se você deseja que o contador comece com algum outro valor (geralmente 1), pode dar isso como segundo argumento para enumerate
.
item
, poderá remover o parêntese: D
yield
/ yield from
, ou expressões geradoras, que implicitamente yield
); enumerate
não é um gerador. Para todos os propósitos relacionados à digitação de patos, não há diferença, mas a verificação explícita de tipo e os documentos da linguagem Python usam apenas o termo "gerador" para um propósito, que não abrange enumerate
.
Estou lendo um livro ( Effective Python ) de Brett Slatkin e ele mostra outra maneira de iterar sobre uma lista e também conhecer o índice do item atual na lista, mas ele sugere que é melhor não usá-lo e usá-lo enumerate
. Eu sei que você perguntou o que enumerar significa, mas quando entendi o seguinte, também entendi como a enumerate
iteração em uma lista é feita, ao mesmo tempo em que o índice do item atual é mais fácil (e mais legível).
list_of_letters = ['a', 'b', 'c']
for i in range(len(list_of_letters)):
letter = list_of_letters[i]
print (i, letter)
A saída é:
0 a
1 b
2 c
Eu também costumava fazer algo ainda mais bobinho antes de ler sobre a enumerate
função.
i = 0
for n in list_of_letters:
print (i, n)
i += 1
Produz a mesma saída.
Mas com enumerate
eu só tenho que escrever:
list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
print (i, letter)
Como outros usuários mencionaram, enumerate
é um gerador que adiciona um índice incremental ao lado de cada item de um iterável.
Então, se você tem uma lista digamos l = ["test_1", "test_2", "test_3"]
, o list(enumerate(l))
lhe dará algo como isto: [(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]
.
Agora, quando isso é útil? Um possível caso de uso é quando você deseja iterar sobre os itens e deseja pular um item específico que apenas conhece seu índice na lista, mas não seu valor (porque seu valor não é conhecido no momento).
for index, value in enumerate(joint_values):
if index == 3:
continue
# Do something with the other `value`
Portanto, seu código é melhor porque você também pode fazer um loop for regular, range
mas para acessar os itens necessários para indexá-los (por exemplo, joint_values[i]
).
Embora outro usuário tenha mencionado uma implementação do enumerate
uso zip
, acho que uma maneira mais pura (mas um pouco mais complexa) sem usar itertools
é a seguinte:
def enumerate(l, start=0):
return zip(range(start, len(l) + start), l)
Exemplo:
l = ["test_1", "test_2", "test_3"]
enumerate(l)
enumerate(l, 10)
Resultado:
[(0, 'teste_1'), (1, 'teste_2'), (2, 'teste_3')]
[(10, 'teste_1'), (11, 'teste_2'), (12, 'teste_3')]
Conforme mencionado nos comentários, essa abordagem com range não funcionará com iterables arbitrários como a enumerate
função original .
itertools
é que sua range
abordagem funciona apenas com contêineres. enumerate
trabalha com iterables arbitrários; se você deseja iterar um arquivo, for lineno, line in enumerate(myfile):
funciona, mas não pôde fazê-lo range(len(myfile))
porque o comprimento não é conhecido até atingir o EOF.
A função enumerar funciona da seguinte maneira:
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)
A saída é
(0, 'I like movie')
(1, " But I don't like the cast")
(2, ' The story is very nice')