Je comprends qu'ils sont tous les deux essentiellement la même chose, mais en termes de style, quel est le meilleur (le plus pythonique) à utiliser pour créer une liste vide ou un dict?
Je comprends qu'ils sont tous les deux essentiellement la même chose, mais en termes de style, quel est le meilleur (le plus pythonique) à utiliser pour créer une liste vide ou un dict?
Réponses:
En termes de vitesse, il n'y a pas de concurrence pour les listes / dictionnaires vides:
>>> from timeit import timeit
>>> timeit("[]")
0.040084982867934334
>>> timeit("list()")
0.17704233359267718
>>> timeit("{}")
0.033620194745424214
>>> timeit("dict()")
0.1821558326547077
et pour les non-vides:
>>> 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
De plus, l'utilisation de la notation entre crochets vous permet d'utiliser des compréhensions de liste et de dictionnaire, ce qui peut être une raison suffisante.
timeit()
fonction signale le temps total pour exécuter un nombre spécifié d'itérations, ce qui est 1000000
par défaut. Ainsi, les exemples ci-dessus indiquent le nombre de secondes pour exécuter l'extrait de code un million de fois. Par exemple timeit('dict()', number=1) // -> 4.0531158447265625e-06
(une itération) while timeit('dict()') // -> 0.12412905693054199
(un million d'itérations)
À mon avis, []
et {}
sont les moyens les plus pythoniques et les plus lisibles de créer des listes / dictionnaires vides.
Se méfier de set()
's cependant, par exemple:
this_set = {5}
some_other_set = {}
Cela peut être déroutant. Le premier crée un ensemble avec un élément, le second crée un dict vide et non un ensemble.
{}
crée toujours un dict vide. {1,2,3}
crée un ensemble dans 2.7+ mais il s'agit d'une erreur de syntaxe dans 2.6
et les versions antérieures.
some_epic_set
qui pointe vers un dict
objet vide ... ce n'est pas un ensemble vide. Pour un ensemble vide, vous devez utiliser set()
.
{5}
crée un ensemble avec un élément, 5
et {}
est un dict vide.
{*()}
pour créer un vide set
avec une syntaxe littérale. Je l'appelle l'opérateur de singe borgne. :-)
Le littéral dict peut - être un petit peu plus vite que son bytecode est plus courte:
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
Il en va de même pour le list
vs[]
CALL_FUNCTION
prend au moins autant de temps que BUILD_MAP
(la fonction appelée est essentiellement BUILD_MAP
), et LOAD_GLOBAL
prend juste une surcharge supplémentaire.
IMHO, en utilisant list()
et dict()
fait que votre Python ressemble à C. Ugh.
Dans le cas de la différence entre [] et list (), il y a un piège que je n'ai vu personne d'autre signaler. Si vous utilisez un dictionnaire comme membre de la liste, les deux donneront des résultats entièrement différents:
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]
utilisant list((foo_dict,))
. La list()
méthode prend un itérable car il ne s'agit que d'un paramètre et l'itère pour ajouter des éléments à la liste. Cela causera un piège similaire en faisant list(some_list)
ce qui aplatira la liste.
list () et [] fonctionnent différemment:
>>> 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 () crée toujours un nouvel objet dans le tas, mais [] peut réutiliser la cellule mémoire pour de nombreuses raisons.
il y a une différence de comportement entre [] et list () comme le montre l'exemple ci-dessous. nous devons utiliser list () si nous voulons que la liste des nombres soit renvoyée, sinon nous obtenons un objet map! Je ne sais pas comment l'expliquer.
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
Une paire de crochets correspond à un objet de liste ou à un indice d'index, ma_Liste [x].
Une paire d'accolades indique un objet dictionnaire.
a_list = ['activé', 'désactivé', 1, 2]
a_dict = {on: 1, off: 2}
C'est principalement une question de choix la plupart du temps. C'est une question de préférence.
Notez cependant que si vous avez des touches numériques par exemple, vous ne pouvez pas le faire:
mydict = dict(1="foo", 2="bar")
Tu dois faire:
mydict = {"1":"foo", "2":"bar"}
mydict = {1:"foo", 2:"bar"}
(sans guillemets pour les clés).
list(i for i in range(10) if i % 2)