Stavo giocando con le list comprehensions per comprenderne meglio e ho trovato alcuni output inaspettati che non sono in grado di spiegare. Non ho trovato questa domanda prima, ma se è/è/una domanda ricorrente, mi scuso.Python: Advanced Nested List Comprehension Sintassi
Stavo essenzialmente cercando di scrivere un generatore che generasse generatori. Un semplice generatore che utilizza di lista sarebbe simile a questa:
(x for x in range(10) if x%2==0) # generates all even integers in range(10)
Quello che stavo cercando di fare è stato scrivere un generatore che ha generato due generatori - il primo dei quali generati i numeri pari nella gamma (10) e il secondo di cui ha generato i numeri dispari nell'intervallo (10). Per questo, ho fatto:
>>> (x for x in range(10) if x%2==i for i in range(2))
<generator object <genexpr> at 0x7f6b90948f00>
>>> for i in g.next(): print i
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <genexpr>
UnboundLocalError: local variable 'i' referenced before assignment
>>> g.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> g = (x for x in range(10) if x%2==i for i in range(2))
>>> g
<generator object <genexpr> at 0x7f6b90969730>
>>> g.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <genexpr>
UnboundLocalError: local variable 'i' referenced before assignment
Non capisco il motivo per cui 'i' viene fatto riferimento prima dell'assegnazione
ho pensato che potrebbe aver avuto qualcosa a che fare con i in range(2)
, così ho fatto:
>>> g = (x for x in range(10) if x%2==i for i in [0.1])
>>> g
<generator object <genexpr> at 0x7f6b90948f00>
>>> g.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <genexpr>
UnboundLocalError: local variable 'i' referenced before assignment
Questo non aveva senso per me, quindi ho pensato che fosse meglio provare qualcosa di più semplice prima. Così sono tornato a liste e provato:
>>> [x for x in range(10) if x%2==i for i in range(2)]
[1, 1, 3, 3, 5, 5, 7, 7, 9, 9]
che mi aspettavo di essere lo stesso:
>>> l = []
>>> for i in range(2):
... for x in range(10):
... if x%2==i:
... l.append(x)
...
>>> l
[0, 2, 4, 6, 8, 1, 3, 5, 7, 9] # so where is my list comprehension malformed?
Ma quando ho provato su un sospetto, questo ha funzionato:
>>> [[x for x in range(10) if x%2==i] for i in range(2)]
[[0, 2, 4, 6, 8], [1, 3, 5, 7, 9]] # so nested lists in nested list comprehension somehow affect the scope of if statements? :S
Quindi ho pensato che potesse essere un problema con il livello di oscillazione dell'istruzione if
. Così ho provato:
>>> [x for x in range(10) for i in range(2) if x%2==i]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
E ora sono completamente confuso. Qualcuno può spiegare questo comportamento. Non capisco perché la mia comprensione delle liste sia malformata, né comprendo come funzioni l'ambito delle dichiarazioni if
.
Qualsiasi aiuto sarebbe notevolmente apprezzato
Grazie
PS: Mentre a prova di leggere la domanda, mi sono reso conto che questo ha un aspetto un po 'come una domanda compiti a casa - non lo è.
Forse '[x per x nella gamma (10), se x% 2 == i per i in range (2)] 'lavoro? Ho ottenuto 'NameError: name 'i' non è definito' (Python 2.6.2) –
@ManojGovindan: Ho ottenuto esattamente quello che hai ottenuto (Python 2.6.5) – inspectorG4dget
Correlati: [Python list comprehension rebind names anche dopo scope of comprehension . È giusto?] (Http://stackoverflow.com/q/4198906) –