[]
보다 빠른 이유는 무엇 list()
입니까?
가장 큰 이유는 파이썬 list()
이 사용자 정의 함수처럼 취급 한다는 것입니다.list
자신의 서브 클래 싱 된 목록을 사용하거나 deque와 같이 다른 것을 .
로 내장 목록의 새 인스턴스를 즉시 만듭니다 []
.
나의 설명은 당신에게 이것에 대한 직감을 제공하려고합니다.
설명
[]
일반적으로 리터럴 구문이라고합니다.
문법에서는이를 "목록 표시"라고합니다. 문서에서 :
목록 표시는 대괄호로 묶인 빈 일련의 표현식입니다.
list_display ::= "[" [starred_list | comprehension] "]"
목록 표시는 새 목록 객체를 생성하며, 내용은 표현식 목록 또는 이해로 지정됩니다. 쉼표로 구분 된 표현식 목록이 제공되면 해당 요소가 왼쪽에서 오른쪽으로 평가되어 순서대로 목록 오브젝트에 배치됩니다. 이해가 제공 될 때,리스트는 이해의 결과로 구성되는 요소들로 구성됩니다.
요컨대 이것은 유형의 내장 객체를 의미합니다. list
가 작성 .
이것을 피할 수는 없습니다. 즉, 파이썬은 최대한 빨리 할 수 있습니다.
반면 list()
에 내장을 만드는 것을 가로 챌 수 있습니다list
, 내장 목록 생성자를 사용하여 내장 .
예를 들어, 목록이 시끄럽게 생성되기를 원한다고 가정 해보십시오.
class List(list):
def __init__(self, iterable=None):
if iterable is None:
super().__init__()
else:
super().__init__(iterable)
print('List initialized.')
그런 다음 list
모듈 수준 전역 범위 에서 이름을 가로 챌 수 있으며 list
,를 만들 때 실제로 하위 유형 목록을 만듭니다.
>>> list = List
>>> a_list = list()
List initialized.
>>> type(a_list)
<class '__main__.List'>
마찬가지로 전역 네임 스페이스에서 제거 할 수 있습니다.
del list
내장 네임 스페이스에 넣습니다.
import builtins
builtins.list = List
그리고 지금:
>>> list_0 = list()
List initialized.
>>> type(list_0)
<class '__main__.List'>
그리고리스트 디스플레이는 무조건리스트를 만듭니다.
>>> list_1 = []
>>> type(list_1)
<class 'list'>
아마도이 작업은 일시적으로 만 수행되므로 변경 사항을 취소하십시오. 먼저 List
내장에서 새 객체를 제거하십시오 .
>>> del builtins.list
>>> builtins.list
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'builtins' has no attribute 'list'
>>> list()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'list' is not defined
아뇨, 우리는 원본을 잃어 버렸습니다.
걱정할 필요는 없지만 여전히 list
목록 리터럴의 유형입니다.
>>> builtins.list = type([])
>>> list()
[]
그래서...
[]
보다 빠른 이유는 무엇 list()
입니까?
우리가 보았 듯이 덮어 쓸 수는 list
있지만 리터럴 유형의 생성을 가로 챌 수는 없습니다. 우리가 사용할 때는 list
어떤 것이 있는지 확인하기 위해 조회를해야합니다.
그런 다음 우리가 찾은 호출 가능한 것을 호출해야합니다. 문법에서 :
호출은 일련의 빈 인수로 호출 가능한 객체 (예 : 함수)를 호출합니다.
call ::= primary "(" [argument_list [","] | comprehension] ")"
우리는 목록뿐만 아니라 모든 이름에 대해 동일한 작업을 수행한다는 것을 알 수 있습니다.
>>> import dis
>>> dis.dis('list()')
1 0 LOAD_NAME 0 (list)
2 CALL_FUNCTION 0
4 RETURN_VALUE
>>> dis.dis('doesnotexist()')
1 0 LOAD_NAME 0 (doesnotexist)
2 CALL_FUNCTION 0
4 RETURN_VALUE
들어 []
파이썬 바이트 코드 수준에서 함수 호출이 없다 :
>>> dis.dis('[]')
1 0 BUILD_LIST 0
2 RETURN_VALUE
바이트 코드 수준에서 조회하거나 호출하지 않고 목록을 작성하는 것입니다.
결론
우리는 그 입증 list
범위 지정 규칙을 사용하여 사용자 코드를 가로 챌 수 있습니다, 그 list()
다음 호출에 대한 외모와 그것을 호출합니다.
반면 []
목록 표시 또는 리터럴은 이름 조회 및 함수 호출을 피합니다.
()
그리고''
그들은 단지 비어 있지있는 한, 특수, 그들은, 그리고 같은, 그것은 그들을 싱글을 할 수있는 쉬운 승리는 불변입니다있는 거; 그들은 심지어 새로운 객체를 만들지 않고 emptytuple
/에 대한 싱글 톤을로드합니다str
. 기술적으로 구현 세부 사항,하지만 나는 그들이 왜 힘든 시간의 상상이 않을 것이다 빈 캐시tuple
/를str
성능상의 이유로합니다. 대한 직관 그래서[]
및{}
주식 문자를 다시 통과 잘못하지만 적용됩니까()
와''
.