Entiendo que ambos son esencialmente lo mismo, pero en términos de estilo, ¿cuál es el mejor (más Pythonic) para usar para crear una lista vacía o un dictado?
Entiendo que ambos son esencialmente lo mismo, pero en términos de estilo, ¿cuál es el mejor (más Pythonic) para usar para crear una lista vacía o un dictado?
Respuestas:
En términos de velocidad, no hay competencia para listas / dictados vacíos:
>>> from timeit import timeit
>>> timeit("[]")
0.040084982867934334
>>> timeit("list()")
0.17704233359267718
>>> timeit("{}")
0.033620194745424214
>>> timeit("dict()")
0.1821558326547077
y para no vacíos:
>>> 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
Además, el uso de la notación entre corchetes le permite usar listas y comprensiones de diccionario, lo que puede ser motivo suficiente.
timeit()
función informa la cantidad total de tiempo para ejecutar un número específico de iteraciones, que es la 1000000
predeterminada. Entonces, los ejemplos anteriores son la cantidad de segundos para ejecutar el fragmento de código un millón de veces. Por ejemplo timeit('dict()', number=1) // -> 4.0531158447265625e-06
(una iteración) mientras timeit('dict()') // -> 0.12412905693054199
(un millón de iteraciones)
En mi opinión []
y {}
son las formas más pitónicas y legibles de crear listas / dictados vacíos.
Tenga cuidado con set()
, por ejemplo:
this_set = {5}
some_other_set = {}
Puede resultar confuso. El primero crea un conjunto con un elemento, el segundo crea un dict vacío y no un conjunto.
{}
siempre crea un dict vacío. {1,2,3}
crea un conjunto en 2.7+ pero es un error de sintaxis en 2.6
y versiones anteriores.
some_epic_set
que apunta a un dict
objeto vacío ... no es un conjunto vacío. Para un juego vacío necesitas usar set()
.
{5}
crea un conjunto con un elemento 5
y {}
es un dict vacío.
{*()}
para hacer un vacío set
con sintaxis literal. Yo lo llamo el operador del mono tuerto. :-)
El literal dict podría ser un pequeño poco más rápido como su código de bytes es más corto:
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 mismo se aplica al list
vs[]
CALL_FUNCTION
tome al menos tanto tiempo como BUILD_MAP
(la función que se llama esencialmente BUILD_MAP
), y solo LOAD_GLOBAL
requiere una sobrecarga adicional.
En mi humilde opinión, usando list()
y dict()
hace que su Python se vea como C. Ugh.
En el caso de la diferencia entre [] y list (), hay un error que no he visto señalar a nadie más. Si usa un diccionario como miembro de la lista, los dos darán resultados completamente diferentes:
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]
utilizando list((foo_dict,))
. El list()
método toma un iterable como único parámetro y lo repite para agregar elementos a la lista. Esto provocará un error similar al hacerlo, list(some_list)
lo que aplanará la lista.
list () y [] funcionan de manera diferente:
>>> 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 () siempre crea un nuevo objeto en el montón, pero [] puede reutilizar la celda de memoria por muchas razones.
hay una diferencia de comportamiento entre [] y list () como muestra el ejemplo siguiente. necesitamos usar list () si queremos que se devuelva la lista de números, de lo contrario, obtenemos un objeto de mapa. Aunque no estoy seguro de cómo explicarlo.
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
Un par de corchetes denota uno de un objeto de lista, o un subíndice de índice, my_List [x].
Un par de llaves denota un objeto de diccionario.
a_list = ['encendido', 'apagado', 1, 2]
a_dict = {encendido: 1, apagado: 2}
Es principalmente una cuestión de elección la mayor parte del tiempo. Es una cuestión de preferencia.
Sin embargo, tenga en cuenta que si tiene teclas numéricas, por ejemplo, eso no puede hacer:
mydict = dict(1="foo", 2="bar")
Tu tienes que hacer:
mydict = {"1":"foo", "2":"bar"}
mydict = {1:"foo", 2:"bar"}
(sin comillas para las claves).
list(i for i in range(10) if i % 2)