developer tip

dict ()와 {}의 차이점은 무엇입니까?

copycodes 2020. 12. 3. 08:01
반응형

dict ()와 {}의 차이점은 무엇입니까?


그래서 제가 사전을 만들고 싶다고합시다. 우리는 그것을이라고 부를 것 d입니다. 하지만 파이썬에서 사전을 초기화하는 방법은 여러 가지가 있습니다! 예를 들어 다음과 같이 할 수 있습니다.

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빈 사전 을 만들어야한다고하자 . 내가 할 때 파이썬 인터프리터의 배후에 무엇을가는 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 내장입니다. 정말 똑똑하거나 헌신적 인 사람 (나가 아님)이 통역사 출처를보고 더 많은 것을 알려줄 수 있습니다. dis.dis를 보여주고 싶었습니다. :)


성능에 관한 한 :

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

@Jacob : 객체가 할당되는 방식에는 차이가 있지만 기록 중 복사가 아닙니다. 파이썬은 (채울 때까지) 사전 객체를 빠르게 할당 할 수있는 고정 된 크기의 "자유 목록"을 할당합니다. {}구문 (또는에 대한 C 호출)을 통해 할당 된 사전 PyDict_New은이 무료 목록에서 올 수 있습니다. 딕셔너리가 더 이상 참조되지 않으면 빈 목록으로 반환되고 해당 메모리 블록을 재사용 할 수 있습니다 (필드가 먼저 재설정 되더라도).

이 첫 번째 사전은 즉시 사용 가능한 목록으로 반환되고 다음 사전은 메모리 공간을 재사용합니다.

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

참조를 유지하면 다음 사전은 다음 빈 슬롯에서 나옵니다.

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

하지만 해당 사전에 대한 참조를 삭제하고 해당 슬롯을 다시 해제 할 수 있습니다.

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

Since the {} syntax is handled in byte-code it can use this optimization mentioned above. On the other hand dict() is handled like a regular class constructor and Python uses the generic memory allocator, which does not follow an easily predictable pattern like the free list above.

Also, looking at compile.c from Python 2.6, with the {} syntax it seems to pre-size the hashtable based on the number of items it's storing which is known at parse time.


Basically, {} is syntax and is handled on a language and bytecode level. dict() is just another builtin with a more flexible initialization syntax. Note that dict() was only added in the middle of 2.x series.


Update: thanks for the responses. Removed speculation about copy-on-write.

One other difference between {} and dict is that dict always allocates a new dictionary (even if the contents are static) whereas {} doesn't always do so (see mgood's answer for when and why):

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

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

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

produces:

$ ./mumble.py
11642752 11642752
11867168 11867456

I'm not suggesting you try to take advantage of this or not, it depends on the particular situation, just pointing it out. (It's also probably evident from the disassembly if you understand the opcodes).


dict() is used when you want to create a dictionary from an iterable, like :

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

Funny usage:

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)

output:

I want to be printed
a

In order to create an empty set we should use the keyword set before it i.e set() this creates an empty set where as in dicts only the flower brackets can create an empty dict

Lets go with an example

print isinstance({},dict) 
True 
print isinstance({},set) 
False 
print isinstance(set(),set) 
True

참고URL : https://stackoverflow.com/questions/664118/whats-the-difference-between-dict-and

반응형