for row_number, row in enumerate(cursor):
Python'da ne yapar ?
enumerate
Bu bağlamda ne anlama geliyor?
for row_number, row in enumerate(cursor):
Python'da ne yapar ?
enumerate
Bu bağlamda ne anlama geliyor?
Yanıtlar:
enumerate()
Fonksiyon bir iterable için bir sayaç ekler.
Yani cursor
içerideki her eleman için bir tuple üretilir (counter, element)
; for
döngü bağlandığı bu row_number
ve row
sırasıyla.
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
Varsayılan olarak, enumerate()
saymaya başlar, 0
ancak buna ikinci bir tam sayı argümanı verirseniz, bunun yerine bu sayıdan başlar:
>>> for count, elem in enumerate(elements, 42):
... print count, elem
...
42 foo
43 bar
44 baz
enumerate()
Python'da yeniden uygulayacak olsaydınız, bunu başarmanın iki yolu var; biri itertools.count()
sayma işlemini yapmak için, diğeri bir jeneratör fonksiyonunda manuel sayma :
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)
ve
def enumerate(it, start=0):
count = start
for elem in it:
yield (count, elem)
count += 1
C gerçek uygulaması ortak tek bir demet nesnesini yeniden yakın ikincisine, optimizasyonlar ile for i, ...
olan (durum açma ve karşı bir Python tamsayı nesnesini kullanarak engellemek için çok büyük hale gelene kadar sayaç için standart bir C tam sayı değeri ile sınırsız).
Üzerinde yinelenebilen bir nesne döndüren yerleşik bir işlevdir. Belgelere bakın .
Kısacası, bir yinelenebilir öğenin (bir liste gibi) öğelerinin yanı sıra bir demet halinde birleştirilmiş bir dizin numarasının üzerinden geçer:
for item in enumerate(["a", "b", "c"]):
print item
baskılar
(0, "a")
(1, "b")
(2, "c")
Bir sekans (veya başka bir yinelenebilir şey) üzerinde döngü yapmak ve ayrıca bir indeks sayacını kullanmak istiyorsanız yararlıdır. Sayacın başka bir değerden (genellikle 1) başlamasını istiyorsanız, bunu ikinci argüman olarak verebilirsiniz enumerate
.
item
parantezleri kaldırabilirsiniz: D
yield
/ yield from
veya jeneratör ifadeleri kullanarak yield
); enumerate
bir jeneratör değil. Ördek yazmayla ilgili tüm amaçlar için hiçbir fark yoktur, ancak açık tür denetimi ve Python dil dokümanları, kapsamı olmayan bir amaç için yalnızca "jeneratör" terimini kullanır enumerate
.
Ben Brett Slatkin tarafından bir kitap ( Etkili Python ) okuyorum ve o bir liste üzerinde yineleme ve aynı zamanda listedeki geçerli öğenin dizinini bilmek için başka bir yol gösterir ama o kullanmak ve enumerate
bunun yerine kullanmak daha iyi olduğunu önerir . Numaralandırmanın ne anlama geldiğini sorduğunuzu biliyorum, ancak aşağıdakileri anladığımda enumerate
, mevcut öğenin dizinini daha kolay (ve daha okunabilir) bilirken bir liste üzerinde yinelemenin nasıl yapıldığını da anladım .
list_of_letters = ['a', 'b', 'c']
for i in range(len(list_of_letters)):
letter = list_of_letters[i]
print (i, letter)
Çıktı:
0 a
1 b
2 c
Ayrıca bir şey yapıyordum, enumerate
fonksiyon hakkında okumadan önce daha da kirli .
i = 0
for n in list_of_letters:
print (i, n)
i += 1
Aynı çıktıyı üretir.
Ama enumerate
ben sadece yazmak zorundayım:
list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
print (i, letter)
Diğer kullanıcıların belirttiği gibi, enumerate
bir yinelenebilir her öğenin yanına artımlı bir dizin ekleyen bir jeneratör.
Bir liste söz sahibi, yani l = ["test_1", "test_2", "test_3"]
, list(enumerate(l))
size böyle bir şey verecektir: [(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]
.
Şimdi, bu ne zaman yararlıdır? Olası bir kullanım durumu, öğeler üzerinde yineleme yapmak istediğinizde ve yalnızca dizininde bildiğiniz belirli bir öğeyi atlamak istediğinizde, değerini değil (değer o anda bilinmediği için).
for index, value in enumerate(joint_values):
if index == 3:
continue
# Do something with the other `value`
Bu nedenle kodunuz daha iyi okunur, çünkü aynı zamanda döngü için bir düzenli de yapabilirsiniz, range
ancak daha sonra bunları dizine eklemeniz gereken öğelere erişmek için (örn joint_values[i]
.).
Başka bir kullanıcı kullanımın bir uygulamasından bahsetse de, enumerate
kullanmadan zip
daha saf (ama biraz daha karmaşık) bir yol olduğunu düşünüyorum itertools
:
def enumerate(l, start=0):
return zip(range(start, len(l) + start), l)
Misal:
l = ["test_1", "test_2", "test_3"]
enumerate(l)
enumerate(l, 10)
Çıktı:
[(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]
[(10, 'test_1'), (11, 'test_2'), (12, 'test_3')]
Yorumlarda belirtildiği gibi, menzil ile bu yaklaşım, orijinal enumerate
fonksiyonun yaptığı gibi rastgele tekrarlanabilirlerle çalışmaz.
itertools
sizin olmasıdır range
yaklaşım sadece konteynerlerin ile çalışır. enumerate
keyfi yinelenebilirlerle çalışır; bir dosyayı yinelemek istiyorsanız for lineno, line in enumerate(myfile):
çalışır, ancak yapamazsınız range(len(myfile))
çünkü EOF'a ulaşana kadar uzunluk bilinmiyor.
Numaralandırma işlevi aşağıdaki gibi çalışır:
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)
Çıktı
(0, 'I like movie')
(1, " But I don't like the cast")
(2, ' The story is very nice')