Вопрос

Итак, допустим, я хочу составить словарь.Мы назовем это d.Но существует несколько способов инициализации словаря в Python!Например, я мог бы сделать это:

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

Или я мог бы сделать это:

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

Или это, как ни странно:

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

Или это:

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

И целым другим множеством способов с dict() функция.Так что, очевидно, одна из вещей dict() обеспечивает гибкость синтаксиса и инициализации.Но это не то, о чем я спрашиваю.

Скажи, что я должен был сделать d просто пустой словарь.Что происходит за кулисами интерпретатора Python, когда я делаю d = {} против d = dict()?Это просто два способа сделать одно и то же?Использует ли {} иметь дополнительный призыв к dict()?Есть ли у одного (даже незначительно) больше накладных расходов, чем у другого?Хотя вопрос на самом деле совершенно неважный, это любопытство, на которое я хотел бы получить ответ.

Это было полезно?

Решение

>>> 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(), по-видимому, является каким-то встроенным в C.Действительно умный или преданный делу человек (не я) мог бы взглянуть на источник перевода и рассказать вам больше.Я просто хотел выпендриться, дис.дис.:)

Другие советы

Что касается производительности:

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

@Джейкоб:Существует разница в том, как распределяются объекты, но они не копируются при записи.Python выделяет "свободный список" фиксированного размера, в котором он может быстро выделять объекты словаря (до тех пор, пока он не заполнится).Словари , выделенные с помощью {} синтаксис (или вызов C для PyDict_New) могут быть взяты из этого бесплатного списка.Когда на словарь больше не ссылаются, он возвращается в список свободных, и этот блок памяти можно использовать повторно (хотя сначала поля сбрасываются).

Этот первый словарь немедленно возвращается в список свободных, а следующий будет повторно использовать свое пространство памяти:

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

Если вы сохраните ссылку, следующий словарь будет получен из следующего свободного слота:

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

Но мы можем удалить ссылку на этот словарь и снова освободить его слот:

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

С тех пор как {} синтаксис обрабатывается в байт-коде, он может использовать эту оптимизацию, упомянутую выше.С другой стороны dict() обрабатывается как обычный конструктор класса, а Python использует универсальный распределитель памяти, который не следует легко предсказуемому шаблону, подобному свободному списку выше.

Кроме того, рассматривая compile.c из Python 2.6, с {} синтаксис похоже, что хэш-таблица предварительно определяет размер на основе количества хранимых в ней элементов, которое известно во время синтаксического анализа.

По сути, {} - это синтаксис, который обрабатывается на уровне языка и байт-кода.dict() - это просто еще один встроенный компонент с более гибким синтаксисом инициализации.Обратите внимание, что dict() был добавлен только в середине серии 2.x.

Обновить:спасибо за ответы.Удалены предположения о копировании при записи.

Еще одно различие между {} и dict это что dict всегда выделяет новый словарь (даже если содержимое является статическим), тогда как {} не делает всегда сделайте это (см. ответ мгуда когда и почему):

def dict1():
    return {'a':'b'}

def dict2():
    return dict(a='b')

print id(dict1()), id(dict1())
print id(dict2()), id(dict2())

производит:

$ ./mumble.py
11642752 11642752
11867168 11867456

Я не предлагаю вам пытаться воспользоваться этим преимуществом или нет, это зависит от конкретной ситуации, просто указываю на это.(Это также, вероятно, очевидно из разборка если вы понимаете коды операций).

dict() используется, когда вы хотите создать словарь из итерируемого, например :

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

Забавное использование:

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)

выходной сигнал:

I want to be printed
a

Чтобы создать пустой набор, мы должны использовать ключевое слово set перед ним то есть set() это создает пустой набор, где, как и в dicts, только цветочные скобки могут создавать пустой dict

Давайте рассмотрим пример

print isinstance({},dict) 
True 
print isinstance({},set) 
False 
print isinstance(set(),set) 
True
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top