Pourquoi Python fonctionne différemment lors d'une itération à l'aide de numéros d'index? Par exemple, avec la fonction zip (qui n'a pas d'index lorsqu'elle est utilisée dans la boucle for), une valeur n'est pas stockée dans une variable. Alors qu'avec la fonction enumerate () (qui me permet d'avoir un "index" dans la boucle foor), cela se passe normalement.
Une solution qui n'utilise pas index a des valeurs différentes pour ma variable "width" lorsque j'essaye de l'imprimer à l'intérieur et à l'extérieur de la boucle, ici la fonction zip () a été utilisée pour travailler avec les deux listes au en même temps sans avoir à gérer leurs index:
8 5 5 [8, 5, 5]
Le code ci-dessus produit la sortie non souhaitée suivante:
tableData = [['apples', 'oranges', 'cherries', 'banana'], ['Alice', 'Bob', 'Carol', 'David'], ['dogs', 'cats', 'moose', 'goose']] def printTable(myListOfLists): colWidths = [0] * len(myListOfLists) for index, lists in enumerate(myListOfLists): for item in lists: if colWidths[index] < len(item): colWidths[index] = len(item) print(colWidths[index]) #This prints my 'width' rightly print(colWidths) #This ALSO prints my 'width' rightly printTable(tableData)
Mais si j'utilise enumerate () (générant des index pour travailler avec les deux listes en même temps) les valeurs modifiées dans ma boucle for seront correctement enregistrées dans la variable width, voir l'exemple de code:
8 5 5 [0, 0, 0]
Cette deuxième sortie est:
tableData = [['apples', 'oranges', 'cherries', 'banana'], ['Alice', 'Bob', 'Carol', 'David'], ['dogs', 'cats', 'moose', 'goose']] def printTable(myListOfLists): colWidths = [0] * len(myListOfLists) for lists, width in zip(myListOfLists, colWidths): for item in lists: if width < len(item): width = len(item) print(width) #This prints my 'width' rightly print(colWidths) #This prints my 'width' wrongly printTable(tableData)
Alors, s'il vous plaît, comment puis-je travailler avec le zip () et avoir mon Variable "externe" modifiée? Qu'est-ce que je fais mal? Merci.
3 Réponses :
Je crois que ce que vous voulez réaliser est d'obtenir la longueur de l'élément le plus long dans une sous-liste donnée à partir de tableData
. Pour ce faire, vous pouvez obtenir la plus longue chaîne de la sous-liste, puis mesurer sa longueur comme ceci:
tableData = [['apples', 'oranges', 'cherries', 'banana'], ['Alice', 'Bob', 'Carol', 'David'], ['dogs', 'cats', 'moose', 'goose']] def printTable(myListOfLists): colWidths = [] for sub_list in myListOfLists: longest_item = max(sub_list, key=len) colWidths.append(len(longest_item)) print(colWidths) printTable(tableData)
modifier avec une explication:
En utilisant pour les listes, width in zip (myListOfLists, colWidths):
à chaque cycle que vous obtenez
1) liste unique avec des chaînes de tableData sous forme de listes
.
2) entier, exactement 0 à partir de colWidths comme width
ensuite, lors de l'itération sur chaque texte comme 'pommes', 'oranges' etc.
ce que vous fais ici:
width = len (item)
c'est comme dire "maintenant width n'est plus 0, c'est len (item)
, par ceci vous n'affectez pas la liste colWidths
parce que vous ne travaillez pas avec, vous manipulez cette valeur 0
, elle n'est pas liée à la place dans la liste colWidths
, c'est juste 0 qui est remplacé par len (item)
sous le nom "width".
J'ai essayé de laisser votre code autant que possible dans la forme originale, c'est pourquoi il existe différentes conventions de dénomination (une avec des traits de soulignement et une avec CamelCase)
Damian, merci mais j'essaye de: 1) comprendre pourquoi mon code ne fonctionne pas comme prévu. 2) comprendre comment cela peut fonctionner en utilisant le zip, le for et le if. Même si ce n'est pas la meilleure solution. Merci pour votre solution, mais elle ne répond toujours pas à ma question.
Oh, désolé alors. Je vais éditer le message avec une explication.
C'est à des fins d'apprentissage, comprenez-vous? J'ai besoin de comprendre pourquoi cela se comporte de cette manière. Alors je ne répéterai pas la même erreur. Désolé, mais si vous pouviez ajouter ces "détails" à votre réponse.
Aucun problème! C'est encore plus motivant pour moi d'expliquer! Ma réponse peut être un peu chaotique, mais j'espère que vous comprendrez.
De cette façon, vous ne changerez pas la valeur de la liste dont vous avez besoin de l'index pour changer la valeur réelle.
example:
for i, (a, b) in enumerate(zip(alist, blist)): print i, a, b
un bon moyen de résoudre votre problème:
tableData = [['apples', 'oranges', 'cherries', 'banana'], ['Alice', 'Bob', 'Carol', 'David'], ['dogs', 'cats', 'moose', 'goose']] def printTable(myListOfLists): colWidths = [0] * len(myListOfLists) for index, row in enumerate(myListOfLists): colWidths[index] = len(max(row, key=len)) print(colWidths) printTable(tableData)
ou
tableData = [['apples', 'oranges', 'cherries', 'banana'], ['Alice', 'Bob', 'Carol', 'David'], ['dogs', 'cats', 'moose', 'goose']] data = [len(max(e, key=len)) for e in tableData] print(data)
d'une autre main que vous pourriez essayer.
for e in [1, 2, 3]: e = 10 # this way is wrong data = [1, 2, 3] for index, e in enumerate(data): e[index] = 50 # always it is needed an index
Merci, je pense que vous y avez pleinement répondu. Spécialement pour être si objectif et pour "for i, (a, b) in enumerate (zip (alist, blist))): print i, a, b"
enumerate
est une manière pythonique de générer des indices (similaire, mais plus idiomatique, for i in range (len (...):
alist = [1,2,3,4] for i in alist: i = 5 # does nothing to alist for i in range(4): alist[i] = 5 # changes an element of alist
En
width = len (item)
, vous réaffectez la variable (en changeant sa valeur d'une liste à une autre)width
avec la valeurlen (item)
, vous ne travaillez pas avec la liste mais avec la variable elle-même. Dans le second scénario,colWidths
est également une liste mais vous l'affectez en changeant l'élément sous un certain index.S'il vous plaît, quelle est la bonne façon de le faire alors? @Damian