web-dev-qa-db-fra.com

Modification des éléments de la liste dans la boucle (python)

J'essaie de modifier les éléments d'une liste à l'aide d'une boucle for, mais un message d'erreur s'affiche (voir ci-dessous). Exemple de code:

#!/usr/bin/env python
# *-* coding: utf8 *-*

data = []
data.append("some")
data.append("example")
data.append("data")
data.append("here")

for item in data:
    data[item] = "everything"

Erreur:

Traceback (most recent call last):
  File "./testy.py", line 11, in <module>
    data[item] = "everything"
TypeError: list indices must be integers, not str

Y a-t-il un moyen de résoudre ce problème?

26
Mateusz Jagiełło

Essayez ceci à la place:

for i in xrange(len(data)):
    data[i] = "everything"

Le problème de base que vous rencontrez est que lorsque vous écrivez data[i], avec data étant une liste, la i doit être un entier, un index numérique dans la liste. Mais dans la boucle

for item in data

item est la chose réelle qui est dans la liste, c’est-à-dire une chaîne de caractères, pas l’index numérique de la chose. xrange est un itérateur qui produit des nombres au lieu des valeurs de la liste, vous pouvez donc l'utiliser.

Une alternative serait

for i, _ in enumerate(data):
    data[i] = "everything"

La fonction enumerate vous donne un itérateur sur des nuplets de la forme (index, item). Il vous suffit donc de prendre l'index et d'oublier l'élément. Je ne suis pas sûr que l'une ou l'autre manière (enumerate ou xrange) soit nettement plus rapide ou meilleure, car je pense que les listes stockent leur longueur dans une variable de manière à pouvoir y accéder rapidement sans compter les éléments de la liste.

Cependant, si vous avez besoin de l'ancienne valeur de liste pour calculer la nouvelle valeur de liste, la méthode enumerate sera probablement un peu plus rapide car vous éviterez à Python de rechercher l'élément dans la liste:

for i, item in enumerate(data):
    data[i] = func(item)

Ce genre de chose s’exprime mieux sous forme de liste de compréhension, cependant:

data = [func(item) for item in data]

Lorsque vous faites cela, Python examine chaque élément de data, y applique la fonction et construit automatiquement une nouvelle liste à partir des résultats. Vous n'avez donc pas à vous soucier de placer le résultat de func(item) au bon endroit de la liste. liste. Votre exemple original pourrait en fait être exprimé par

data = ["everything" for item in data]
64
David Z

Les éléments de la liste sont accessibles par index entier, i. e. dans votre exemple data[1] == 'example'. C'est pourquoi Python se plaint lorsque vous utilisez une chaîne comme recherche.

Si vous souhaitez rechercher un élément dans une liste par sa valeur, vous pouvez utiliser data.index("value"):

data[data.index("some")] = "something else"

Mais si vous voulez simplement les survoler, utilisez enumerate() comme David l’a suggéré.

5
Tim Pietzcker

l'indexation d'une liste à l'aide d'entiers pourrait être inefficace. Il est probable que python stocke les éléments de la liste en utilisant une table liée avec des pointeurs sous-jacents. Dans ce cas, pour trouver un élément spécifique, python doit parcourir la liste jusqu'au i-ème élément.

Il est suggéré que l’utilisation du format suivant pourrait être efficace: A [:] = [x * x pour x dans a]

0
Jingpeng Wu