Soru 'For' döngülerindeki dizine erişme?


Aşağıdaki gibi bir liste için dizinin kendisine nasıl erişirim?

ints = [8, 23, 45, 12, 78]

Kullanarak bir döngü kullanarak for döngü, bu durumda 1'den 5'e kadar döngü dizinine nasıl erişirim?


2563
2018-02-06 22:47


Menşei




Cevaplar:


Dizin değişkeni (normalde C veya PHP gibi dillerde kullanacağınız) gibi bir ek durum değişkeninin kullanılması, pythonik olmayan olarak kabul edilir.

Daha iyi seçenek yerleşik işlevi kullanmaktır enumerate()Python 2 ve 3'te de kullanılabilir:

for idx, val in enumerate(ints):
    print(idx, val)

Çıkış yapmak PEP 279 daha fazlası için.


4457
2018-02-06 22:52



Aaron'un aşağıda belirttiği gibi, 0-4 yerine 1-5 almak istiyorsanız start = 1 kullanın. - clozach


Bir for döngüsü kullanarak, bu durumda 1'den 5'e kadar döngü dizinine nasıl erişebilirim?

kullanım enumerate Dizini, yinelediğiniz gibi öğe ile almak için:

for index, item in enumerate(items):
    print(index, item)

Ve Python'un indekslerinin sıfırdan başladığını, dolayısıyla yukarıdaki ile 0 ila 4 arasında olacağını unutmayın. 1 ila 5 sayısını istiyorsanız, şunu yapın:

for count, item in enumerate(items, start=1):
    print(count, item)

Tek kontrolsüz kontrol akışı

İstediğiniz şey, alt düzey dillerin çoğu programcısının kullanacağı algoritma olan, aşağıdaki Pythonic eşdeğeridir:

index = 0            # Python's indexing starts at zero
for item in items:   # Python's for loops are a "for each" loop 
    print(index, item)
    index += 1

Ya da her bir döngü için olmayan dillerde:

index = 0
while index < len(items):
    print(index, items[index])
    index += 1

ya da bazen Python'da daha yaygın (ancak tekdüze olmayan) bulunur:

for index in range(len(items)):
    print(index, items[index])

Numaralandırma İşlevini Kullan

Python en enumerate fonksiyon indeksler için muhasebeyi gizleyerek ve tekrarlanabilirliği başka bir tekrarlanabilir hale getirerek görsel dağınıklığı azaltır (bir enumerate nesne), endeksin iki öğeli bir kopyasını ve orijinal yinelenebilirliğin sağlayacağı öğeyi verir. Şuna benziyor:

for index, item in enumerate(items, start=0):   # default is zero
    print(index, item)

Bu kod örneği oldukça iyi standart Python'un deyimsel kodu ile kod arasındaki farkın örneği. İdyitik kod karmaşıktır (ancak karmaşık değildir) Python, kullanılması amaçlanan şekilde yazılmıştır. Deyimsel kod, dilin tasarımcıları tarafından beklenir, bu da genellikle bu kodun sadece daha okunabilir değil, aynı zamanda daha verimli olduğunu gösterir.

Saymak

İndekslere ihtiyacınız olmasa da, yinelemelerin sayılmasına ihtiyaç duyarsınız (bazen arzu edilir). 1 ve son numara senin sayın olacak.

for count, item in enumerate(items, start=1):   # default is zero
    print(item)

print('there were {0} items printed'.format(count))

Sayı 1'den 5'e kadar istediğini söylediğinde (indeksin aksine) sormayı istediğin şey gibi görünüyor.


Aşağı kırmak - adım adım açıklama

Bu örnekleri aşmak için, bir endeksle yinelemek istediğimiz öğelerin bir listesini aldığımızı varsayalım:

items = ['a', 'b', 'c', 'd', 'e']

Şimdi bu numaralandırmayı numaralandırmak için bir numaralandırma nesnesi oluşturuyoruz:

enumerate_object = enumerate(items) # the enumerate object

İlk maddeyi bu döngüden çıkartabileceğimiz bir döngü içinde next fonksiyon:

iteration = next(enumerate_object) # first iteration from enumerate
print(iteration)

Ve biz bir tuple elde ederiz 0, ilk endeks ve 'a', ilk öğe:

(0, 'a')

"olarak adlandırılan şeyi kullanabiliriz"sekans açılışı"Bu iki parçalı elemanları ayıklamak için:

index, item = iteration
#   0,  'a' = (0, 'a') # essentially this.

ve incelediğimizde index, ilk indeksi 0, ve item ilk maddeye atıfta bulunur 'a'.

>>> print(index)
0
>>> print(item)
a

Sonuç

  • Python indeksleri sıfırdan başlar
  • Bu dizinleri yinelediğiniz şekilde yinelemeli olarak almak için numaralandırma işlevini kullanın.
  • Numaralandırmayı deyimsel yolla (tuple paket açma ile birlikte) daha okunabilir ve sürdürülebilir kodlar oluşturur:

Yani şunu yap:

for index, item in enumerate(items, start=0):   # Python indexes start at zero
    print(index, item)

519
2018-01-21 17:11





Başlamak için oldukça basit 1 ondan başka 0:

for index, item in enumerate(iterable, start=1):
   print index, item

Not

Önemli ipucu, o zamandan beri biraz yanıltıcı index bir olacak tuple  (idx, item) İşte. Gitmek güzel.


105
2018-05-27 10:04



Soru, liste indeksleri hakkındaydı; 0'dan başladıkları için, indeksler yanlış olacağından, diğer sayıdan başlamak için çok az nokta vardır (evet, OP de sorunun yanlış olduğunu söylemiştir). Aksi halde, index, item sadece index not ettiğiniz gibi çok yanıltıcıdır. Sadece kullan for index, item in enumerate(ints). - Antti Haapala
Dizin, parantez çiftlerini (indeks) olarak içine almak daha iyidir, hem Python sürüm 2 ve 3 üzerinde çalışacaktır. - hygull


for i in range(len(ints)):
   print i, ints[i]

67
2018-02-06 22:49



Bu muhtemelen olmalı xrange 3.0 öncesi için. - Ben Blank
Hayır, hız gerekli olmadıkça optimize edilmemelidir. - Georg Schölly
Biri olmamalı zamanından önce Bu davada hemfikir olmakla birlikte, aynı kodun 2.x ve 3.x'te çalışmasından dolayı optimize etmekteyim.
Bunun yerine numaralandırın - saulspatz
Yukarıdaki Python 2.3 için, daha fazla Pythonic olduğu için numaralandırılmış yerleşik işlevi kullanın. - januarvs


Python'da olduğu gibi, bunu yapmak için çeşitli yollar vardır. Bütün örneklerde varsayalım: lst = [1, 2, 3, 4, 5]

1. Numaralandırmayı kullanma (çoğu deyimsel)

for index, element in enumerate(lst):
    # do the things that need doing here

Bu benim görüşümde de en güvenli seçenek çünkü sonsuz yineleme haline gelme şansı ortadan kalktı. Hem öğe hem de endeks değişkenlerde tutulur ve başka kod yazılmasına gerek yoktur. öğeye erişmek için.

2. İndeksi tutmak için değişken oluşturmakullanma for)

for index in range(len(lst)):   # or xrange
    # you will have to write extra code to get the element

3. Dizini tutmak için değişken oluşturmakullanma while)

index = 0
while index < len(lst):
    # you will have to write extra code to get the element
    index += 1  # escape infinite recursion

4. Her zaman başka bir yol var

Daha önce açıklandığı gibi, burada açıklanmayan başka yollar da vardır ve bunlar başka durumlarda daha da uygulanabilir. Örneğin kullanma itertools.chain ile için. Yuvalanmış halkaları diğer örneklerden daha iyi idare eder.


34
2017-08-15 02:17



2. noktada, ile erişim .index() Doğrusal bir karmaşıklığa sahiptir, bu da döngünüzün karmaşıklığının artık ikinci dereceden olduğu anlamına gelir. Dahası, listeniz birkaç eşit öğe içerdiğinde işe yaramaz, çünkü her zaman birincinin dizinini döndürür. - Aristide
@Charitoo point 2'yi kaldırıyorum çünkü gerçekten hiç kullanılmamalıdır - jamylak
Aynı anda birden fazla numaranız olabilir mi? Ben ve J'nin ben J> I, vb. Sanırım bunun için 3 daha iyi olurdu - arviman


Eski moda yol:

for ix in range(len(ints)):
    print ints[ix]

Kavramak listesi:

[ (ix, ints[ix]) for ix in range(len(ints))]

>>> ints
[1, 2, 3, 4, 5]
>>> for ix in range(len(ints)): print ints[ix]
... 
1
2
3
4
5
>>> [ (ix, ints[ix]) for ix in range(len(ints))]
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
>>> lc = [ (ix, ints[ix]) for ix in range(len(ints))]
>>> for tup in lc:
...     print tup
... 
(0, 1)
(1, 2)
(2, 3)
(3, 4)
(4, 5)
>>> 

20
2018-02-06 22:52



Bu değil yanlış ve C / C ++ ve diğerleri kullanılır. Python olmayan olarak kabul edilir, ancak python da kullanılabilir. Kaynaklara ayıran basit çözümler gibi: + - Valor Naram
Nerede yanlış olduğunu söylüyor? - Charlie Martin
Bazı python aşırılık derler, bunu yapma. Ama sadece bir yolun birden fazla olduğunu belirtmek için söyledim. - Valor Naram


Döngü içinde listenin dizinlerine erişmenin en hızlı yolu Python 2.7 kullanmak aralık yöntemi küçük listeler ve numaralandırma yöntemi orta ve büyük boy listeler için.

Bakınız Farklı yaklaşımlar Listede yineleme ve dizin değerine erişmek için kullanılabilir ve performans metrikleri Aşağıdaki kod örneklerinde (sizin için yararlı olacağını varsayalım):

from timeit import timeit

# Using range
def range_loop(iterable):
    for i in range(len(iterable)):
        1 + iterable[i]

# Using xrange
def xrange_loop(iterable):
    for i in xrange(len(iterable)):
        1 + iterable[i]

# Using enumerate
def enumerate_loop(iterable):
    for i, val in enumerate(iterable):
        1 + val

# Manual indexing
def manual_indexing_loop(iterable):
    index = 0
    for item in iterable:
        1 + item
        index += 1

Aşağıdaki her bir yöntem için performans metriklerine bakın:

from timeit import timeit

def measure(l, number=10000):
print "Measure speed for list with %d items" % len(l)
print "xrange: ", timeit(lambda :xrange_loop(l), number=number)
print "range: ", timeit(lambda :range_loop(l), number=number)
print "enumerate: ", timeit(lambda :enumerate_loop(l), number=number)
print "manual_indexing: ", timeit(lambda :manual_indexing_loop(l), number=number)

measure(range(1000))
# Measure speed for list with 1000 items
# xrange:  0.758321046829
# range:  0.701184988022
# enumerate:  0.724966049194
# manual_indexing:  0.894635915756

measure(range(10000))
# Measure speed for list with 100000 items
# xrange:  81.4756360054
# range:  75.0172479153
# enumerate:  74.687623024
# manual_indexing:  91.6308541298

measure(range(10000000), number=100)
# Measure speed for list with 10000000 items
# xrange:  82.267786026
# range:  84.0493988991
# enumerate:  78.0344707966
# manual_indexing:  95.0491430759

Sonuç olarak, range yöntem 1000 öğe ile listelenecek en hızlı olanıdır. > 10 000 bedenli liste için enumerate kazanan.

Aşağıda bazı yararlı bağlantılar ekleme:


16
2017-08-04 09:49



"okunabilirlik sayılır" Küçük <1000 aralığında hız farkı önemsizdir. Zaten küçük bir zaman diliminde% 3 daha yavaştır. - Surest Texas