explication - syntaxe for python




Accéder à l'index dans les boucles 'pour'? (14)

Comment puis-je accéder à l'index lui-même pour une liste comme celle-ci?

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

Lorsque j'utilise une boucle for , comment accéder à l'index de la boucle, de 1 à 5 dans ce cas?


À l'aide d'une boucle for, comment accéder à l'index de la boucle, de 1 à 5 dans ce cas?

Utilisez enumerate pour obtenir l'index avec l'élément au fur et à mesure de votre itération:

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

Et notez que les index de Python commencent à zéro, vous obtiendrez donc 0 à 4 avec ce qui précède. Si vous voulez le nombre, 1 à 5, procédez comme suit:

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

Flux de contrôle unidiomatique

Ce que vous demandez, c'est l'équivalent Pythonic de ce qui suit, qui est l'algorithme que la plupart des programmeurs de langages de niveau inférieur utiliseraient:

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

Ou dans des langues qui n'ont pas de boucle for-each:

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

ou parfois plus communément (mais unidiomatiquement) trouvé dans Python:

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

Utiliser la fonction énumérer

La fonction enumerate de Python réduit l'encombrement visuel en masquant la comptabilisation des index et en encapsulant l'itérable dans un autre objet itérable (objet enumerate ) qui produit un tuple à deux éléments de l'index et celui que l'itéré d'origine fournirait. Cela ressemble à ceci:

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

Cet exemple de code est assez bien l'exemple canonical de la différence entre un code idiomatique de Python et un code non. Le code idiomatique est sophistiqué (mais pas compliqué) en Python, écrit de la manière dont il était destiné. Le code idiomatique est attendu par les concepteurs du langage, ce qui signifie qu’il est généralement non seulement plus lisible, mais également plus efficace.

Obtenir un compte

Même si vous n'avez pas besoin d'index au fur et à mesure, mais vous avez besoin d'un décompte des itérations (parfois souhaitable), vous pouvez commencer avec 1 et le nombre final sera votre décompte.

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

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

Le nombre semble être plus ce que vous avez l'intention de demander (par opposition à index) lorsque vous avez dit que vous vouliez de 1 à 5.

Décomposer - une explication étape par étape

Pour décomposer ces exemples, supposons que nous ayons une liste d'éléments sur lesquels nous souhaitons effectuer une itération avec un index:

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

Nous passons maintenant cet itératif à énumérer, créant un objet énumérer:

enumerate_object = enumerate(items) # the enumerate object

Nous pouvons extraire le premier élément de cette liste que nous pourrions mettre en boucle avec la fonction next :

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

Et nous voyons que nous obtenons un tuple de 0 , le premier index, et 'a' , le premier élément:

(0, 'a')

nous pouvons utiliser ce que l'on appelle " séquence de décompression " pour extraire les éléments de ce double-tuple:

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

et lorsque nous inspectons index , nous constatons qu'il fait référence au premier index, 0, et que l' item rapporte au premier élément, 'a' .

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

Conclusion

  • Les index Python commencent à zéro
  • Pour obtenir ces index à partir d'un itérable lorsque vous le parcourez, utilisez la fonction énumérer
  • Utiliser énumérer de manière idiomatique (avec la décompression de tuple) crée un code plus lisible et maintenable:

Alors faites ceci:

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

C'est assez simple de le démarrer à partir de 1 autre que 0 :

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

Remarque

index important, bien qu'un peu trompeur puisque index sera un tuple (idx, item) ici. Bon aller.


Comme c'est la norme en Python, il y a plusieurs façons de le faire. Dans tous les exemples supposons: lst = [1, 2, 3, 4, 5]

1. Utiliser énumérer ( considéré comme le plus idiomatique )

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

C'est aussi l'option la plus sûre à mon avis car les chances d'entrer dans une récursion infinie ont été éliminées. L'élément et son index sont tous deux contenus dans des variables et il n'est pas nécessaire d'écrire un code supplémentaire pour accéder à l'élément.

2. Créer une variable pour contenir l’index ( utiliser for )

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

3. Créer une variable pour contenir l'index (en utilisant while )

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

4. Il y a toujours un autre moyen

Comme expliqué précédemment, il existe d'autres moyens de le faire qui n'ont pas été expliqués ici et ils peuvent même s'appliquer davantage dans d'autres situations. par exemple, utiliser itertools.chain avec pour. Il gère les boucles imbriquées mieux que les autres exemples.


Dans votre question, vous écrivez "comment accéder à l'index de boucle, de 1 à 5 dans ce cas?"

Cependant, l'index d'une liste commence à zéro. Nous devons donc savoir si vous souhaitez réellement obtenir l'index et l'élément de chaque élément d'une liste, ou si vous souhaitez réellement que les nombres commencent par 1. Heureusement, en python, il est facile d'effectuer l'une ou les deux.

Tout d'abord, pour clarifier, la fonction énumérer renvoie de manière itérative l'index et l'élément correspondant pour chaque élément d'une liste.

alist = [ 1, 2, 3, 4, 5 ]

for n,a in enumerate(alist):
    print( "%d %d"%(n,a) )

La sortie pour ce qui précède est alors,

0 1
1 2
2 3
3 4
4 5

Notez que l'index va de 0. Ce type d'indexation est courant parmi les langages de programmation modernes, notamment python et c.

Si vous souhaitez que votre boucle couvre une partie de la liste, vous pouvez utiliser la syntaxe python standard pour une partie de la liste. Par exemple, pour faire une boucle à partir du deuxième élément de la liste sans inclure le dernier élément, vous pouvez utiliser

for n,a in enumerate(alist[1:-1]):
    print( "%d %d"%(n,a) )

Notez que, une fois encore, l’index de sortie court de 0,

0 2
1 3
2 4

Cela nous amène au début = n commutateur pour enumerate (). Cela compense simplement l'index, vous pouvez simplement ajouter un nombre équivalent à l'index à l'intérieur de la boucle.

for n,a in enumerate(alist,start=1):
    print( "%d %d"%(n,a) )

pour lequel la sortie est

1 1
2 2
3 3
4 4
5 5

L'utilisation d'une variable d'état supplémentaire, telle qu'une variable d'index (que vous utiliseriez normalement dans des langages tels que C ou PHP), est considérée comme non pythonique.

La meilleure option consiste à utiliser la fonction intégrée enumerate() , disponible à la fois en Python 2 et 3:

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

Découvrez PEP 279 pour plus.


La meilleure solution à ce problème est d’ énumérer la fonction python intégrée.
énumérer le tuple de retour
la première valeur est index
la deuxième valeur est un élément du tableau à cet index

In [1]: ints = [8, 23, 45, 12, 78]

In [2]: for idx, val in enumerate(ints):
   ...:         print(idx, val)
   ...:     
(0, 8)
(1, 23)
(2, 45)
(3, 12)
(4, 78)

Manière ancienne:

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

Compréhension de la liste:

[ (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)
>>> 

Pour imprimer un tuple de (index, valeur) en compréhension de liste à l'aide d'une boucle for :

ints = [8, 23, 45, 12, 78]
print [(i,ints[i]) for i in range(len(ints))]

Sortie:

[(0, 8), (1, 23), (2, 45), (3, 12), (4, 78)]

S'il n'y a pas de doublon dans la liste:

for i in ints:
        indx=ints.index(i)
        print(i,indx)

Utilisez plutôt enumerate.

for counter, value in enumerate(ints):
    print(counter, value)

OU utiliser ci-dessous:

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

Selon cette discussion: http://bytes.com/topic/python/answers/464012-objects-list-index

Boucle compteur itération

L'idiome actuel pour la boucle sur les index utilise la fonction intégrée "range":

for i in range(len(sequence)):
    # work with index i

La boucle sur les éléments et les index peut être réalisée soit par l'ancien langage, soit en utilisant la nouvelle fonction intégrée 'zip' [2]:

for i in range(len(sequence)):
    e = sequence[i]
    # work with index i and element e

ou

for i, e in zip(range(len(sequence)), sequence):
    # work with index i and element e

via http://www.python.org/dev/peps/pep-0212/


Vous avez reçu un certain nombre de réponses expliquant enumerate , mais si vous avez seulement besoin de l'index pour accéder aux entrées correspondantes dans deux listes, il existe un autre moyen plus simple et plus propre en Python 3: zip .

Par exemple, si vous utilisez l'index pour extraire les noms correspondants des numéros de votre liste, vous pouvez le faire comme suit:

ints = [8, 23, 45, 12, 78]
names = ["John", "Sue", "Johannes", "Patel", "Ian"]
for int, name = zip(ints, names):
    print("{} - {}".format(name, int)

Cela produirait

8 - John
23 - Sue
45 - Johannes
12 - Patel
78 - Ian

Vous pouvez aussi essayer ceci:

data = ['itemA.ABC', 'itemB.defg', 'itemC.drug', 'itemD.ashok']
x = []
for (i, item) in enumerate(data):
      a = (i, str(item).split('.'))
      x.append(a)
for index, value in x:
     print(index, value)

La sortie est

0 ['itemA', 'ABC']
1 ['itemB', 'defg']
2 ['itemC', 'drug']
3 ['itemD', 'ashok']

Vous pouvez utiliser la méthode index

ints = [8, 23, 45, 12, 78]
inds = [ints.index(i) for i in ints]

EDIT Souligné dans le commentaire que cette méthode ne fonctionne pas s'il y a des doublons dans ints , la méthode ci-dessous devrait fonctionner pour toutes les valeurs dans ints :

ints = [8, 8, 8, 23, 45, 12, 78]
inds = [tup[0] for tup in enumerate(ints)]

Ou bien

ints = [8, 8, 8, 23, 45, 12, 78]
inds = [tup for tup in enumerate(ints)]

si vous voulez obtenir à la fois l'index et la valeur en ints sous forme de liste de nuplets.

Il utilise la méthode d’ enumerate dans la réponse sélectionnée à cette question, mais avec une compréhension de liste, ce qui le rend plus rapide avec moins de code.


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




list