[] 및 {} vs list () 및 dict (), 어느 것이 더 낫습니까?


113

나는 그것들이 본질적으로 동일하다는 것을 이해하지만 스타일 측면에서 빈 목록이나 사전을 만드는 데 사용하는 것이 더 나은 (더 Pythonic) 하나입니까?

답변:


197

속도면에서 빈 목록 / 딕셔너리에 대한 경쟁이 아닙니다.

>>> from timeit import timeit
>>> timeit("[]")
0.040084982867934334
>>> timeit("list()")
0.17704233359267718
>>> timeit("{}")
0.033620194745424214
>>> timeit("dict()")
0.1821558326547077

비어 있지 않은 경우 :

>>> 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

또한 대괄호 표기법을 사용하면 목록 및 사전 이해를 사용할 수 있으므로 충분한 이유가 될 수 있습니다.


4
영어 이름을 사용하여 사전 및 목록 이해도 수행 할 수 있습니다. 예 :list(i for i in range(10) if i % 2)
Zags

4
{} 및 []이 훨씬 더 빠른 이유가 있습니까? 나는 그들이 단순히 별칭이라고 생각했습니다.
Justin D.

정확한 시간을 제공하지 않는 것 같습니다. 벤치 마크에 따르면 일반 http 호출보다 훨씬 느린 ~ 200ms가 소요되는 것 같습니다. 쉘에서 dict ()를 정상적으로 실행 한 다음 timeit ( "dict ()")를 실행하면 실행에 눈에 띄는 차이가 있습니다.
piyush

2
@piyush 실제로이 timeit()함수는 1000000기본적으로 지정된 반복 횟수를 실행하는 데 걸리는 총 시간을보고합니다 . 따라서 위의 예는 코드 조각을 백만 번 실행하는 데 걸리는 시간 (초)입니다. 예 : timeit('dict()', number=1) // -> 4.0531158447265625e-06(1 회 반복) while timeit('dict()') // -> 0.12412905693054199(백만 반복)
Greg Haskins

@GregHaskins이 경우 백만 개의 레코드를 반복하고 루프에서 dict ()를 사용하지 않는 한 dict () 또는 {} 사용에 대해 걱정할 필요가 없습니다.
piyush

37

내 의견 []{}빈 목록 / dicts을 생성 할 수있는 가장 파이썬 읽을 수있는 방법이 있습니다.

주의하십시오 set(), 예를 들어,하지만이야 '

this_set = {5}
some_other_set = {}

혼란 스러울 수 있습니다. 첫 번째는 하나의 요소로 집합을 만들고 두 번째 는 집합이 아닌 빈 사전을 만듭니다 .


4
{}항상 빈 사전을 만듭니다. {1,2,3}2.7+에서 세트를 생성하지만 2.6및 이전 버전에서는 구문 오류입니다 .
ThiefMaster 2011

1
죄송합니다? 그것은 some_epic_setdict개체를 가리키는 이름 을 가진 변수입니다 . 그것은 빈 집합이 아닙니다. 빈 세트의 경우 set().
6502

2
6502 @ : 사실,하지만 일반적인 함정이다 {5}하나 개의 요소 세트를 생성 5하고 {}빈 딕셔너리이다.
orlp

1
와, 헷갈리네요. 그래도 Fractal of Bad Design 수준의 혼란이 아닙니다. :-)
Prof. Falken

4
@EnderLook : 사실, 일반화 된 압축 해제 를 사용 {*()}하면 set리터럴 구문으로 비워 두는 데 사용할 수 있습니다 . 나는 그것을 외눈 박이 원숭이 운영자라고 부릅니다. :-)
ShadowRanger

17

DICT의 문자가있을 수 있습니다 작은 그 바이트 코드가 짧은로 빠른 비트 :

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

list대 에도 동일하게 적용됩니다.[]


8
이는 BUILD_MAP 및 LOAD_GLOBAL이 일정한 시간이고 동일한 시간이 걸린다고 가정합니다. 가능성이 거의 없습니다. timeit는 훨씬 더 나은 추정치를 제공합니다.
Jamie Pate

가능성, CALL_FUNCTION필요 이상으로 많은 시간과 같이 BUILD_MAP(기능이 필수적이라는 것이다되는 BUILD_MAP), 및 LOAD_GLOBAL단지 추가적인 오버 헤드가 걸린다.
chepner

3

IMHO, 사용 list()하고 dict()Python을 C. Ugh처럼 보이게 만듭니다.


3

[]와 list ()의 차이의 경우 다른 사람이 지적하지 않은 함정이 있습니다. 사전을 목록의 구성원으로 사용하면 두 가지 결과가 완전히 다릅니다.

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]를 사용 하는 것과 동일한 결과를 얻을 수 있습니다 list((foo_dict,)). 이 list()메서드는 유일한 매개 변수이므로 iterable을 취하고 목록에 요소를 추가하기 위해 반복합니다. 이것은 list(some_list)목록을 평평하게 만드는 유사한 함정을 유발 합니다.
sotrh

1

list ()와 []는 다르게 작동합니다.

>>> 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 ()는 항상 힙에 새 객체를 생성하지만 []는 여러 가지 이유로 메모리 셀을 재사용 할 수 있습니다.


0

아래 예제와 같이 []와 list () 사이의 동작에는 한 가지 차이점이 있습니다. 숫자 목록을 반환하려면 list ()를 사용해야합니다. 그렇지 않으면지도 객체를 얻습니다! 그래도 설명하는 방법을 모르겠습니다.

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

여기에 range () 함수의 예제를 사용하여 동작에 대한 설명이있는 것 같습니다. >>> print (range (10)) # range (0, 10) range ()는 목록처럼 동작하지만 목록이 아닙니다. 그것은 당신이 그것을 반복 할 때 시퀀스에서 연속적인 항목을 반환하는 객체이며, 실제로 목록을 만들지 않아 공간을 절약합니다. 이러한 객체는 반복 가능합니다. 즉, 공급이 고갈 될 때까지 연속 항목을 얻을 수있는 무언가를 기대하는 함수 및 구성의 대상으로 적합합니다. list () 함수는
이터 러블

1
그 결과 []는 반복 가능한 객체를 저장합니다. list ()는 동일한 iterable에서 목록을 만듭니다
sebtac

0

상자 괄호 쌍은 목록 객체 또는 색인 아래 첨자 인 my_List [x] 중 하나를 나타냅니다.

중괄호 쌍은 사전 객체를 나타냅니다.

a_list = [ 'on', 'off', 1, 2]

a_dict = {켜기 : 1, 끄기 : 2}


-5

대부분의 경우 주로 선택의 문제입니다. 그것은 선호도의 문제입니다.

그러나 예를 들어 숫자 키가있는 경우 다음을 수행 할 수 없습니다.

mydict = dict(1="foo", 2="bar")

너가해야되는:

mydict = {"1":"foo", "2":"bar"}

7
이것은 잘못된 것입니다 ... 당신이해야 할 일입니다 mydict = {1:"foo", 2:"bar"}(키에 대한 따옴표없이).
6502

8
단순히 "잘못"이 아닙니다. 키는 인용 여부에 따라 문자열 / 정수입니다.
ThiefMaster 2011
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.