문제

그래서 내가 사전을 만들고 싶다고 가정 해 봅시다. 우리는 그것을 부를 것입니다 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 빈 사전. 내가 할 때 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 내장 된 것입니다. 정말 똑똑하거나 헌신적 인 사람 (나가 아님)은 통역사 소스를보고 더 많은 것을 알려줄 수 있습니다. 방금 Dis.Dis를 과시하고 싶었습니다. :)

다른 팁

성능이 진행되는 한 :

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

@Jacob : 객체가 할당되는 방식에는 차이가 있지만 복사하지 않습니다. Python은 고정 된 크기의 "무료 목록"을 할당하여 사전 객체를 신속하게 할당 할 수 있습니다 (채워질 때까지). 사전을 통해 할당 된 사전 {} 구문 (또는 C 호출 PyDict_New)이 무료 목록에서 나올 수 있습니다. 사전이 더 이상 참조되지 않으면 무료 목록으로 돌아가고 해당 메모리 블록을 재사용 할 수 있습니다 (필드가 먼저 재설정되지만).

이 첫 번째 사전은 즉시 무료 목록으로 돌아오고 다음은 메모리 공간을 재사용합니다.

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

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

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

그러나 우리는 해당 사전에 대한 참조를 삭제하고 슬롯을 다시 자유롭게 할 수 있습니다.

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

이후 {} 구문은 바이트 코드로 처리되어 위에서 언급 한이 최적화를 사용할 수 있습니다. 반면에 dict() 일반 클래스 생성자처럼 처리되고 Python은 일반 메모리 할당기를 사용하는데, 위의 무료 목록과 같은 쉽게 예측 가능한 패턴을 따르지 않습니다.

또한 Python.C에서 Compile.c를보고 {} 구문은 구문 분석 시간에 알려진 저장 품목의 수를 기반으로 해시 테이블의 미리 크기로 보입니다.

기본적으로 {}는 구문이며 언어 및 바이트 코드 수준으로 처리됩니다. Dict ()는보다 유연한 초기화 구문이있는 또 다른 내장입니다. Dict ()는 2.x 시리즈 중간에만 추가되었습니다.

업데이트: 답변 주셔서 감사합니다. 복사기 쓰기에 대한 추측을 제거했습니다.

또 다른 차이점 {} 그리고 dict 그게 다 dict 항상 새로운 사전을 할당합니다 (내용이 정적 인 경우에도) {} 그렇지 않습니다 언제나 그렇게하십시오 (참조 Mgood의 대답 언제, 왜) :) :

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

나는 당신이 이것을 활용하려고 시도하지 않는다고 제안하지 않습니다. 그것은 특정 상황에 달려 있고, 그것을 지적하는 것뿐입니다. (아마도 아마도 분명 할 것입니다 분해 opcodes를 이해한다면).

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() 이것은 꽃 괄호만이 빈 덕트를 만들 수있는 곳과 마찬가지로 빈 세트를 만듭니다.

예를 들어 보자

print isinstance({},dict) 
True 
print isinstance({},set) 
False 
print isinstance(set(),set) 
True
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top