2013-06-06 11 views
6
>>> [l for l in range(2,100) if litheor(l)!=l in sieve(100)] 
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] 
>>> 2 in sieve(100) 
True 
>>> litheor(2) 
True 

Così litheor(2) è True e 2 in sieve(100) è True, quindi la clausola if nella lista di comprensione è False. Ma perché 2 è ancora nell'output della comprensione della lista?Python: qualcosa è andato storto da qualche parte nella comprensione della lista?

risposta

11

Ok, in un primo momento che sembra folle, ma:

>>> True != 2 in [2,3,5] 
True 
>>> (True != 2) in [2,3,5] 
False 
>>> True != (2 in [2,3,5]) 
False 

Quando ti rendi conto che questo non è un semplice problema di precedenza, guardando l'AST è l'unica opzione che rimane:

>>> ast.dump(ast.parse("True != 2 in [2,3,5]")) 
"Module(body=[Expr(value= 
Compare(left=Name(id='True', ctx=Load()), ops=[NotEq(), In()], comparators=[Num(n=2), List(elts=[Num(n=2), Num(n=3), Num(n=5)], ctx=Load())]) 
)])" 

ed ecco un piccolo suggerimento:

>>> ast.dump(ast.parse("1 < 2 <= 3")) 
'Module(body=[Expr(value= 
Compare(left=Num(n=1), ops=[Lt(), LtE()], comparators=[Num(n=2), Num(n=3)]) 
)])' 

Così, si scopre, True != 2 in [2,3,5] viene interpretato simile a 1 < 2 <= 3. E la tua espressione

litheor(l) != l in sieve(100) 

significa

litheor(l) != l and l in sieve(100) 

che è True.

+0

Grazie. 1, tuttavia, non è in setaccio (100). C'è qualcos'altro che potrebbe essere andato storto? –

+0

@SylvesterVLowell Beh, potrebbe essere uno dei seguenti: 1) 'sieve (100)' che contiene non solo interi ma anche booleano 'True'; 2) 'litheor (2)' return '2' invece di boolean e' setaccio (100) 'contenenti' 0'. Non riesco a vedere altre opzioni. Potresti mostrarci le tue definizioni di 'setaccio' e' litheor', per favore? – kirelagin

+0

@SylvesterVLowell Oh aspetta ... Hai ragione ... Questo è totalmente folle ... – kirelagin

Problemi correlati