Pergunta

Então, digamos que eu quero fazer um dicionário. Vamos chamá-lo d. Mas existem várias maneiras de inicializar um dicionário em Python! Por exemplo, eu poderia fazer isso:

d = {'hash': 'bang', 'slash': 'dot'}

Ou eu poderia fazer isso:

d = dict(hash='bang', slash='dot')

Ou este, curiosamente:

d = dict({'hash': 'bang', 'slash': 'dot'})

Ou este:

d = dict([['hash', 'bang'], ['slash', 'dot']])

E toda uma outra infinidade de maneiras com a função dict(). Então, obviamente, uma das coisas dict() fornece flexibilidade na sintaxe e de inicialização. Mas isso não é o que eu estou perguntando.

Say eu fosse fazer d apenas um dicionário vazio. O que se passa nos bastidores do interpretador Python quando eu faço d = {} contra d = dict()? É simplesmente duas maneiras de fazer a mesma coisa? Será que usando {} ter o adicional Chamada de dict()? Um tem (mesmo insignificante) mais sobrecarga do que o outro? Enquanto a questão é realmente completamente sem importância, é uma curiosidade que eu gostaria de ter respondido.

Foi útil?

Solução

>>> def f():
...     return {'a' : 1, 'b' : 2}
... 
>>> def g():
...     return dict(a=1, b=2)
... 
>>> g()
{'a': 1, 'b': 2}
>>> f()
{'a': 1, 'b': 2}
>>> import dis
>>> dis.dis(f)
  2           0 BUILD_MAP                0
              3 DUP_TOP             
              4 LOAD_CONST               1 ('a')
              7 LOAD_CONST               2 (1)
             10 ROT_THREE           
             11 STORE_SUBSCR        
             12 DUP_TOP             
             13 LOAD_CONST               3 ('b')
             16 LOAD_CONST               4 (2)
             19 ROT_THREE           
             20 STORE_SUBSCR        
             21 RETURN_VALUE        
>>> dis.dis(g)
  2           0 LOAD_GLOBAL              0 (dict)
              3 LOAD_CONST               1 ('a')
              6 LOAD_CONST               2 (1)
              9 LOAD_CONST               3 ('b')
             12 LOAD_CONST               4 (2)
             15 CALL_FUNCTION          512
             18 RETURN_VALUE        

dict () é, aparentemente, alguns C embutido. Uma pessoa realmente inteligente ou dedicado (não eu) poderia olhar para a fonte intérprete e lhe dizer mais. Eu só queria mostrar dis.dis. :)

Outras dicas

Tanto quanto o desempenho vai:

>>> from timeit import timeit
>>> timeit("a = {'a': 1, 'b': 2}")
0.424...
>>> timeit("a = dict(a = 1, b = 2)")
0.889...

@Jacob: Há uma diferença na forma como os objetos são alocados, mas eles não são copy-on-write. Python aloca um tamanho fixo "lista livre", onde ele pode rapidamente alocar dicionário objetos (até encher). Dicionários alocados via a sintaxe {} (ou uma chamada C para PyDict_New) pode vir a partir desta lista livre. Quando o dicionário não é referenciado ele é retornado para a lista livre e que um bloco de memória pode ser reutilizado (embora os campos são repostos em primeiro lugar).

Este primeiro dicionário é imediatamente voltou para a lista livre, e o próximo será reutilizar seu espaço de memória:

>>> id({})
340160
>>> id({1: 2})
340160

Se você manter uma referência, o próximo dicionário virá a partir do próximo slot livre:

>>> x = {}
>>> id(x)
340160
>>> id({})
340016

Mas podemos excluir a referência a esse dicionário e libertar seu slot novamente:

>>> del x
>>> id({})
340160

Uma vez que a sintaxe {} é tratado em byte-code ele pode usar essa otimização mencionada acima. Por outro lado dict() é tratado como um construtor de classe regular e Python usa o alocador de memória genérica, que não segue um padrão facilmente previsível como o livre lista acima.

Além disso, olhando para compile.c do Python 2.6, com a sintaxe {} parece pré-size o hashtable com base no número de itens que ele está armazenando que é conhecido no momento da análise.

Basicamente, {} é sintaxe e é tratado em um nível de linguagem e bytecode. dict () é apenas mais um builtin com uma sintaxe de inicialização mais flexível. Note-se que dict () só foi adicionado no meio de 2.x série.

dict () é usado quando você quer criar um dicionário de uma iterable, como:

dict( generator which yields (key,value) pairs )
dict( list of (key,value) pairs )

Uso engraçado:

def func(**kwargs):
      for e in kwargs:
        print(e)
    a = 'I want to be printed'
    kwargs={a:True}
    func(**kwargs)
    a = 'I dont want to be printed'
    kwargs=dict(a=True)
    func(**kwargs)

saída:

I want to be printed
a

A fim de criar um conjunto vazio, devemos usar a palavra-chave set antes que ele ou seja set() isso cria um conjunto vazio onde, como em dicts apenas os suportes de flores pode criar um dict vazio

Lets Go com um exemplo

print isinstance({},dict) 
True 
print isinstance({},set) 
False 
print isinstance(set(),set) 
True
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top