Liste Python & pour chaque accès (Rechercher/Remplacer dans la liste)
J'ai d'abord pensé que Python était un pur passe-par-langue de référence.
À venir à partir de C/C++ je ne peux pas aider mais penser à propos de la gestion de la mémoire, et il est difficile de le mettre hors de ma tête. Donc, je suis en train de penser à partir d'une perspective Java et de penser à tout, mais primitives comme un passage par référence.
Problème: j'ai une liste, contenant un tas d'instances d'une classe définie par l'utilisateur.
Si j'utilise le pour-chaque syntaxe, c'est à dire.:
for member in my_list:
print(member.str);
Est member
l'équivalent d'une référence à l'objet?
Est-il l'équivalent de l'action:
i = 0
while i < len(my_list):
print(my_list[i])
i += 1
Je ne pense PAS, parce que quand je suis à la recherche de faire un remplacement, il ne fonctionne pas, c'est que cela ne fonctionne pas:
for member in my_list:
if member == some_other_obj:
member = some_other_obj
Un simple rechercher et remplacer dans une liste. Peut-être que le faire dans une boucle for-each, si oui, comment? D'autre, je n'ai qu'à utiliser le hasard de la syntaxe d'accès (entre crochets), ou ne travaillent pas et j'ai besoin de supprimer l'entrée, et insérez une nouvelle un seul? I. e.:
i = 0
for member in my_list:
if member == some_other_obj:
my_list.remove(i)
my_list.insert(i, member)
i += 1
- Les valeurs ne sont pas copiées au cours d'une itération de la liste. Les raisons sont semblables à pourquoi les objets ne sont pas copiés passés en paramètres à une fonction.
Vous devez vous connecter pour publier un commentaire.
De répondre à ce qui a été bon, les commentaires ont conduit à une amélioration de ma propre compréhension de Python variables.
Comme indiqué dans les commentaires, lorsque vous passez en boucle sur une liste avec quelque chose comme
for member in my_list
lamember
variable est liée à chaque élément de la liste. Cependant, la ré-affectation de la variable dans la boucle n'est pas influer directement sur la liste elle-même. Par exemple, ce code ne changera pas la liste:De sortie:
Si vous souhaitez modifier une liste contenant immuable types de, vous avez besoin de faire quelque chose comme:
De sortie:
Si votre liste contient des objets mutables, vous pouvez modifier le
member
objet directement:Noter que vous n'êtes toujours pas la modification de la liste, il suffit de modifier les objets de la liste.
Vous pouvez bénéficier de la lecture de Nommage et de Liaison.
for idx in range(0, len(my_list)): my_list[idx] = new_obj
Il travaille à mon goût. Je vous remercie.member
n'est pas une copie de la valeur. ideone.com/y7A9Mmember
vous venez de le lier à un autre objet. Et simember
n'est pas l'un des objets de la liste à tout moment, il se réfère à chacun d'eux.Python, Java n'est pas, ni en C/C++ -- vous besoin d'arrêter de penser de cette façon d'utiliser la puissance de Python.
Python n'a pas passé par valeur, ni par référence, mais utilise à la place de passer par nom (ou passe-par-objet) -- en d'autres termes, presque tout est lié à un nom que vous pouvez ensuite utiliser (les deux exceptions évidentes étant tuple - et la liste d'indexation).
Lorsque vous ne
spam = "green"
, vous avez lié le nom despam
à l'objet de type string"green"
; si vous neeggs = spam
vous n'avez pas copié quoi que ce soit, vous n'avez pas fait référence pointeurs; vous avez simplement lié à un autre nom,eggs
, pour le même objet ("green"
dans ce cas). Si vous liez ensuitespam
à autre chose (spam = 3.14159
)eggs
sera toujours lié à"green"
.Lors d'une boucle for s'exécute, il prend le nom que vous lui donnez, et se lie à tour de rôle, chaque objet dans l'objet iterable lors de l'exécution de la boucle; lorsque vous appelez une fonction, il prend les noms en-tête de la fonction et les lie à la arguments passés; attribution d'un nom est en fait la reliaison un nom (il peut prendre un certain temps pour absorber cette -- il l'a fait pour moi, de toute façon).
Avec des boucles en utilisant des listes, il y a deux façons de base pour attribuer retour à la liste:
ou
Avis de la
[:]
sur ce derniersome_list
-- il est à l'origine d'une mutation desome_list
s'éléments (réglage de la chose entière pournew_list
's éléments) au lieu de reconsolidation du nomsome_list
ànew_list
. Est-ce important? Ça dépend! Si vous avez d'autres noms d'ailleurssome_list
lié à la même liste d'objets, et vous voulez pour voir les mises à jour, alors vous devez utiliser la méthode de l'effeuillage; si vous n'en avez pas, ou si vous ne pas voulez voir les mises à jour, puis relier --some_list = new_list
.Vous pouvez remplacer quelque chose là-bas par l'obtention de l'index le long de l'élément.
Noter que si vous souhaitez supprimer un élément de la liste que vous avez à effectuer une itération sur une copie de la liste, sinon vous obtiendrez des erreurs puisque vous essayez de modifier la taille de quelque chose que vous êtes à parcourir. Cela peut se faire assez facilement avec des tranches.
Mal:
Le 2 est encore là parce que nous avons modifié la taille de la liste que nous avons itéré il. La manière correcte serait:
foo = [c for c in foo if condition(c)]
enumerate
tout GreenMat était coincé (il a édité sa réponse) pourfor x in xrange(len())
. Cheersfor x in xrange(len(l))
premier. En tant que tel, j'attendsfor x in xrange(len(l))
sera plus familier quefor x in enumerate(l)
pour quelqu'un venant de C/C++ (qui l'OP professé à l'être). Est-il préférable d'être plus Pythonic ou de se concentrer sur le coeur de l'émission et l'utilisation de plus en plus familiers de la syntaxe sur des choses qui sont nécessaires pour l'exemple, mais pas le nœud du problème? (Je ne pense pas qu'il y a une seule bonne réponse à cette question.)O(N**2)
boucle surfoo[:]
avecfoo.remove()
en elle (3ème exemple). Je n'ai rien contre le premier exemple avecenumerate()
. Il devrait être évident en raison de 1ère et de 3ème des exemples de faire des choses différentes et la compréhension de liste produit un résultat similaire à la 3ème exemple.xrange(len(l))
et ne se sentent pas moins pythonic... 🙂condition
ne semble pas être encombrant et maladroit) Cheers