Capisco che siano entrambi essenzialmente la stessa cosa, ma in termini di stile, qual è il migliore (più Pythonic) da usare per creare un elenco o un dict vuoto?
Capisco che siano entrambi essenzialmente la stessa cosa, ma in termini di stile, qual è il migliore (più Pythonic) da usare per creare un elenco o un dict vuoto?
Risposte:
In termini di velocità, non c'è concorrenza per elenchi / dict vuoti:
>>> from timeit import timeit
>>> timeit("[]")
0.040084982867934334
>>> timeit("list()")
0.17704233359267718
>>> timeit("{}")
0.033620194745424214
>>> timeit("dict()")
0.1821558326547077
e per non vuoti:
>>> timeit("[1,2,3]")
0.24316302770330367
>>> timeit("list((1,2,3))")
0.44744206316727286
>>> timeit("list(foo)", setup="foo=(1,2,3)")
0.446036018543964
>>> timeit("{'a':1, 'b':2, 'c':3}")
0.20868602015059423
>>> timeit("dict(a=1, b=2, c=3)")
0.47635635255323905
>>> timeit("dict(bar)", setup="bar=[('a', 1), ('b', 2), ('c', 3)]")
0.9028228448029267
Inoltre, l'uso della notazione tra parentesi ti consente di utilizzare la comprensione di elenchi e dizionari, il che potrebbe essere un motivo sufficiente.
timeit()
funzione riporta la quantità di tempo totale per eseguire un numero specificato di iterazioni, che è 1000000
per impostazione predefinita. Quindi gli esempi sopra sono il numero di secondi per eseguire lo snippet di codice un milione di volte. Ad esempio timeit('dict()', number=1) // -> 4.0531158447265625e-06
(un'iterazione) mentre timeit('dict()') // -> 0.12412905693054199
(un milione di iterazioni)
Secondo me []
e {}
sono i modi più pitonici e leggibili per creare elenchi / dict vuoti.
Fai attenzione set()
però, ad esempio:
this_set = {5}
some_other_set = {}
Può creare confusione. Il primo crea un set con un elemento, il secondo crea un dict vuoto e non un set.
{}
crea sempre un dict vuoto. {1,2,3}
crea un set in 2.7+ ma è un errore di sintassi nelle 2.6
versioni precedenti e.
some_epic_set
che punta a un dict
oggetto vuoto ... non è un insieme vuoto. Per un set vuoto è necessario utilizzare set()
.
{5}
crea un insieme con un elemento 5
ed {}
è un dict vuoto.
{*()}
per creare un vuoto set
con sintassi letterale. Lo chiamo l'operatore scimmia con un occhio solo. :-)
Il letterale dict potrebbe essere un piccolo po 'più veloce come il suo bytecode è più breve:
In [1]: import dis
In [2]: a = lambda: {}
In [3]: b = lambda: dict()
In [4]: dis.dis(a)
1 0 BUILD_MAP 0
3 RETURN_VALUE
In [5]: dis.dis(b)
1 0 LOAD_GLOBAL 0 (dict)
3 CALL_FUNCTION 0
6 RETURN_VALUE
Lo stesso vale per il list
vs[]
CALL_FUNCTION
richiede almeno tanto tempo quanto BUILD_MAP
(la funzione che viene chiamata essenzialmente lo è BUILD_MAP
) e LOAD_GLOBAL
richiede solo un sovraccarico aggiuntivo.
IMHO, usando list()
e dict()
fa sembrare il tuo Python C. Ugh.
Nel caso della differenza tra [] e list (), c'è una trappola che non ho visto evidenziare da nessun altro. Se utilizzi un dizionario come membro dell'elenco, i due daranno risultati completamente diversi:
In [1]: foo_dict = {"1":"foo", "2":"bar"}
In [2]: [foo_dict]
Out [2]: [{'1': 'foo', '2': 'bar'}]
In [3]: list(foo_dict)
Out [3]: ['1', '2']
[foo_dict]
utilizzando list((foo_dict,))
. Il list()
metodo accetta un iterabile in quanto è l'unico parametro e lo ripete per aggiungere elementi all'elenco. Ciò causerà una simile trappola facendo list(some_list)
che appiattirà l'elenco.
list () e [] funzionano in modo diverso:
>>> def a(p=None):
... print(id(p))
...
>>> for r in range(3):
... a([])
...
139969725291904
139969725291904
139969725291904
>>> for r in range(3):
... a(list())
...
139969725367296
139969725367552
139969725367616
list () crea sempre un nuovo oggetto nell'heap, ma [] può riutilizzare la cella di memoria per molti motivi.
c'è una differenza nel comportamento tra [] e list () come mostra l'esempio seguente. dobbiamo usare list () se vogliamo che la lista dei numeri venga restituita, altrimenti otteniamo un oggetto mappa! Non sono sicuro di come spiegarlo però.
sth = [(1,2), (3,4),(5,6)]
sth2 = map(lambda x: x[1], sth)
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>
sth2 = [map(lambda x: x[1], sth)]
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>
type(sth2) # list
type(sth2[0]) # map
sth2 = list(map(lambda x: x[1], sth))
print(sth2) #[2, 4, 6]
type(sth2) # list
type(sth2[0]) # int
Una coppia di parentesi quadre denota uno di un oggetto elenco o un pedice di indice, my_List [x].
Una coppia di parentesi graffe denota un oggetto dizionario.
a_list = ["on", "off", 1, 2]
a_dict = {on: 1, off: 2}
È principalmente una questione di scelta il più delle volte. È una questione di preferenza.
Nota tuttavia che se ad esempio hai tasti numerici, non puoi farlo:
mydict = dict(1="foo", 2="bar")
Devi fare:
mydict = {"1":"foo", "2":"bar"}
mydict = {1:"foo", 2:"bar"}
(senza virgolette per le chiavi).
list(i for i in range(10) if i % 2)