En Python, vous pouvez avoir plusieurs itérateurs dans une liste de compréhension, comme
[(x,y) for x in a for y in b]
pour certaines séquences appropriées a et b. Je connais la sémantique des boucles imbriquées des compréhensions de liste de Python.
Ma question est: un itérateur dans la compréhension peut-il se référer à l'autre? En d'autres termes: pourrais-je avoir quelque chose comme ceci:
[x for x in a for a in b]
où la valeur actuelle de la boucle extérieure est l'itérateur de l'intérieur?
Par exemple, si j'ai une liste imbriquée:
a=[[1,2],[3,4]]
quelle serait l'expression de compréhension de liste pour atteindre ce résultat:
[1,2,3,4]
?? (Veuillez énumérer uniquement les réponses de compréhension, car c'est ce que je veux savoir).
la source
[x for b in a for x in b]
Cela a toujours été un bug sur python. Cette syntaxe est tellement à l'envers. La forme générale de ax for x in y
toujours la variable directement après le for, alimente l'expression à gauche du for. Dès que vous effectuez une double compréhension, votre variable itérée la plus récente est soudainement "si loin". C'est maladroit, et ne lit pas du tout naturellementJ'espère que cela aide quelqu'un d'autre car
a,b,x,y
cela n'a pas beaucoup de sens pour moi! Supposons que vous ayez un texte plein de phrases et que vous vouliez un tableau de mots.J'aime penser à la compréhension de liste comme étirant du code horizontalement.
Essayez de le décomposer en:
Exemple:
Cela fonctionne également pour les générateurs
la source
Gee, je suppose que j'ai trouvé la réponse: je ne faisais pas assez attention à quelle boucle est intérieure et laquelle est extérieure. La compréhension de la liste doit être comme:
pour obtenir le résultat souhaité, et oui, une valeur actuelle peut être l'itérateur de la boucle suivante.
la source
L'ordre des itérateurs peut sembler contre-intuitif.
Prends pour exemple:
[str(x) for i in range(3) for x in foo(i)]
Décomposons-le:
la source
[(output in loop 2) (loop 1) (loop 2)]
avec(loop 1) = for i in range(3)
et(loop 2) = for x in foo(i):
et(output in loop 2) = str(x)
.ThomasH a déjà ajouté une bonne réponse, mais je veux montrer ce qui se passe:
Je suppose que Python analyse la compréhension de la liste de gauche à droite. Cela signifie que la première
for
boucle qui se produit sera exécutée en premier.Le deuxième "problème" de ceci est que
b
"la fuite" de la compréhension de la liste. Après la première compréhension réussie de la listeb == [3, 4]
.la source
x = 'hello';
[x for x in xrange(1,5)];
print x # x is now 4
Si vous souhaitez conserver le tableau multidimensionnel, il faut imbriquer les supports du tableau. voir l'exemple ci-dessous où un est ajouté à chaque élément.
la source
Cette technique de mémoire m'aide beaucoup:
[ <RETURNED_VALUE> <OUTER_LOOP1> <INNER_LOOP2> <INNER_LOOP3> ... <OPTIONAL_IF> ]
Et maintenant, vous pouvez penser à R eturn + O uter-loop comme le seul R ight O rder
Sachant ci-dessus, l'ordre dans la liste complet même pour 3 boucles semble simple:
car ce qui précède n'est qu'un:
pour itérer une liste / structure imbriquée, la technique est la même: pour
a
la question:pour un autre niveau imbriqué
etc
la source
Je pense que c'est plus facile à comprendre
la source
De plus, vous pouvez utiliser exactement la même variable pour le membre de la liste d'entrée actuellement accessible et pour l'élément à l'intérieur de ce membre. Cependant, cela pourrait même le rendre plus (liste) incompréhensible.
La première
for x in input
est évaluée, conduisant à une liste de membres de l'entrée, puis, Python parcourt la deuxième partiefor x in x
pendant laquelle la valeur x est écrasée par l'élément actuel auquel il accède, puis la premièrex
définit ce que nous voulons retourner.la source
Cette fonction flatten_nlevel appelle récursivement la liste imbriquée1 pour la convertir à un niveau. Essayez ceci
production:
la source
flatten_nlevel(sublist, flat_list)
, non?!