2012-01-09 3 views
5

Eventuali duplicati:
Is it Pythonic to use list comprehensions for just side effects?Utilizzando la comprensione come una scorciatoia per chiamare un metodo più volte

A volte in un file script scriverò qualcosa come [foo(x) for x in (1,2,3)]. Non mi interessa il valore di ritorno (se presente), ho appena preferisco la scorciatoia anziché utilizzare

for x in (1,2,3): 
    foo(x) 

Ma in questa comprensione che sto creando un oggetto di lista ci che in realtà non va da nessuna parte (Credo che viene garbage collection perché nessuno mantiene un riferimento ad essa)

>>> L = list('SxPyAMz') 
>>> [L.remove(c) for c in ('x', 'y', 'z')] 
[None, None, None] 
>>> print L 
['S', 'P', 'A', 'M'] 

la mia domanda:? è questa cattiva pratica, o è del tutto innocuo per l'oggetto da mago inosservati? Se è brutto, c'è un 1-liner migliore per questo tipo di scorciatoie?

risposta

3

Anche in passato ho considerato questa cattiva pratica e l'ho scoraggiata a causa della sepoltura della logica del loop all'interno della comprensione. Ma poi ho trovato la ricetta nel documentation of the itertools module, e l'esempio afferma che fare il looping alla velocità C è di qualche valore in alcuni casi.

La ricetta di consumo utilizza una deque di lunghezza 0 come destinazione dei valori di eliminazione dall'elaborazione ripetuta dell'espressione di lista/generatore.

L = list('SxPyAMz') 
deque((L.remove(c) for c in ('x', 'y', 'z')), maxlen=0) 

si potrebbe fare ciò che abbiamo scritto la definizione di un globale deque 0-length:

_consumer = deque(maxlen=0) 
do_all = _consumer.extend 

L = list('SxPyAMz') 
do_all(L.remove(c) for c in ('x', 'y', 'z')) 
print L 
6

Se non è necessario per memorizzare i risultati di una semplice pianura ciclo "for" lo farà:

for c in ('x', 'y', 'z'): L.remove(c) 
+1

non mi piace questi perché la mancanza di ritorno a capo e un rientro è contro guida di stile pitone. – wim

+1

IMHO la versione one-liner delle strutture di controllo Python è accettabile nei luoghi in cui si desidera utilizzare una comprensione delle liste. Il tuo esempio ha un nome di variabile maiuscolo che è (di nuovo, IMHO) una violazione molto peggiore di PEP8, dal momento che CamelCase dovrebbe essere riservato ai nomi di classe e instance_should_use_underscores. È più semplice e più facile da leggere rispetto a qualsiasi alternativa che conosca. –

+0

Sì, ma era solo per la dimostrazione all'interprete. Non mi vedresti usando una lista chiamata L nel codice di produzione. – wim

7

Sì, direi che è una cattiva pratica che si dovrebbe evitare in quanto, come si già sottolineato, un oggetto viene sostanzialmente creato per essere raccolto in seguito.

Per i modi alternativi di scrivere questa espressione, si prega di dare un'occhiata a questo question.

Problemi correlati