Eu entendo que ambos são essencialmente a mesma coisa, mas em termos de estilo, qual é o melhor (mais pitônico) para usar para criar uma lista vazia ou dict?
Eu entendo que ambos são essencialmente a mesma coisa, mas em termos de estilo, qual é o melhor (mais pitônico) para usar para criar uma lista vazia ou dict?
Respostas:
Em termos de velocidade, não há competição por listas / dictos vazios:
>>> from timeit import timeit
>>> timeit("[]")
0.040084982867934334
>>> timeit("list()")
0.17704233359267718
>>> timeit("{}")
0.033620194745424214
>>> timeit("dict()")
0.1821558326547077
e para não vazio:
>>> 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
Além disso, usar a notação de colchetes permite que você use as compreensões de lista e dicionário, o que pode ser motivo suficiente.
timeit()
função relata a quantidade total de tempo para executar um número especificado de iterações, que é 1000000
por padrão. Portanto, os exemplos acima são o número de segundos para executar o snippet de código um milhão de vezes. Por exemplo timeit('dict()', number=1) // -> 4.0531158447265625e-06
(uma iteração) while timeit('dict()') // -> 0.12412905693054199
(um milhão de iterações)
Na minha opinião []
e {}
são as formas mais pítônicas e legíveis de criar listas / dictos vazios.
set()
Porém, tenha cuidado com o, por exemplo:
this_set = {5}
some_other_set = {}
Pode ser confuso. O primeiro cria um conjunto com um elemento, o segundo cria um dicionário vazio e não um conjunto.
{}
sempre cria um dicionário vazio. {1,2,3}
cria um conjunto no 2.7+, mas é um erro de sintaxe em 2.6
versões anteriores.
some_epic_set
que está apontando para um dict
objeto vazio ... não é um conjunto vazio. Para um conjunto vazio, você precisa usar set()
.
{5}
criar um conjunto com um elemento 5
e {}
é um dicionário vazio.
{*()}
para fazer um vazio set
com a sintaxe literal. Eu chamo isso de operador de macaco caolho. :-)
O literal dict pode ser um minúsculo pouco mais rápido como seu bytecode é mais curto:
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
O mesmo se aplica ao list
vs[]
CALL_FUNCTION
leva pelo menos tanto tempo quanto BUILD_MAP
(a função que está sendo chamada essencialmente BUILD_MAP
) e LOAD_GLOBAL
leva apenas uma sobrecarga adicional.
IMHO, usando list()
e dict()
faz seu Python parecer C. Ugh.
No caso de diferença entre [] e list (), há uma armadilha que não vi ninguém apontar. Se você usar um dicionário como membro da lista, os dois fornecerão resultados totalmente 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]
usando list((foo_dict,))
. O list()
método pega um iterável como único parâmetro e itera sobre ele para adicionar elementos à lista. Isso causará uma armadilha semelhante, o list(some_list)
que achatará a lista.
list () e [] funcionam de forma 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 () sempre cria um novo objeto no heap, mas [] pode reutilizar a célula de memória por vários motivos.
há uma diferença de comportamento entre [] e list () como mostra o exemplo abaixo. precisamos usar list () se quisermos que a lista de números seja retornada, caso contrário, obteremos um objeto de mapa! Não tenho certeza de como explicar isso.
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
Um par de colchetes denota um de um objeto de lista, ou um índice subscrito, my_List [x].
Um par de chaves denota um objeto de dicionário.
a_list = ['ligado', 'desligado', 1, 2]
a_dict = {on: 1, off: 2}
É principalmente uma questão de escolha na maioria das vezes. É uma questão de preferência.
Observe, porém, que se você tiver teclas numéricas, por exemplo, não poderá fazer:
mydict = dict(1="foo", 2="bar")
Você tem que fazer:
mydict = {"1":"foo", "2":"bar"}
mydict = {1:"foo", 2:"bar"}
(sem as aspas para as chaves).
list(i for i in range(10) if i % 2)