Neden daha []
hızlı list()
?
En büyük neden, Python'un list()
kullanıcı tanımlı bir işlev gibi davranmasıdır , bu da başka bir şeyi diğer adlara takma list
ve farklı bir şey (kendi alt sınıf listenizi veya belki de bir deque kullanmak gibi) yaparak araya girebileceğiniz anlamına gelir .
Hemen bir yerleşik listenin yeni bir örneğini oluşturur []
.
Açıklamam size bunun için sezgiyi vermeye çalışıyor.
açıklama
[]
genel olarak değişmez sözdizimi olarak bilinir.
Gramerde buna "liste ekranı" denir. Dokümanlardan :
Liste ekranı, köşeli parantez içine alınmış muhtemelen boş bir ifade dizisidir:
list_display ::= "[" [starred_list | comprehension] "]"
Liste ekranı yeni bir liste nesnesi verir; içindekiler bir ifade listesi veya kavrama ile belirtilir. Virgülle ayrılmış bir ifade listesi sağlandığında, öğeleri soldan sağa değerlendirilir ve bu sırada liste nesnesine yerleştirilir. Anlama sağlandığında, liste kavrama sonucu ortaya çıkan unsurlardan oluşturulur.
Kısacası, bu yerleşik türde bir nesnenin list
yaratıldığı anlamına gelir .
Bunu atlatmak yok - yani Python bunu olabildiğince çabuk yapabilir.
Öte yandan, yerleşik liste yapıcısını kullanarak list()
bir yerleşik oluşturmaktan kesilebilir list
.
Örneğin, listelerimizin gürültülü bir şekilde oluşturulmasını istediğimizi düşünelim:
class List(list):
def __init__(self, iterable=None):
if iterable is None:
super().__init__()
else:
super().__init__(iterable)
print('List initialized.')
Daha sonra list
modül düzeyinde global kapsamdaki adı arayabiliriz ve sonra bir oluşturduğumuzda list
, aslında alt tür listemizi yaratırız:
>>> list = List
>>> a_list = list()
List initialized.
>>> type(a_list)
<class '__main__.List'>
Benzer şekilde, onu global ad alanından kaldırabiliriz
del list
ve yerleşik ad alanına yerleştirin:
import builtins
builtins.list = List
Ve şimdi:
>>> list_0 = list()
List initialized.
>>> type(list_0)
<class '__main__.List'>
Liste ekranının koşulsuz olarak bir liste oluşturduğunu unutmayın:
>>> list_1 = []
>>> type(list_1)
<class 'list'>
Muhtemelen bunu sadece geçici olarak yapıyoruz, bu yüzden değişikliklerimizi geri alalım - önce yeni List
nesneyi yerleşiklerden kaldırın :
>>> 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
Oh, hayır, orijinalin izini kaybettik.
Endişelenmeyin, yine de alabiliriz list
- bu bir liste değişmezinin türüdür:
>>> builtins.list = type([])
>>> list()
[]
Yani...
Neden daha []
hızlı list()
?
Gördüğümüz gibi - üzerine yazabiliriz list
- ancak gerçek türün yaratılmasına müdahale edemeyiz. Kullandığımızda list
, orada bir şey olup olmadığını görmek için arama yapmalıyız.
O zaman aradığımız her çağrılabilir şeyi aramalıyız. Dilbilgisinden:
Bir çağrı, muhtemelen boş bir argüman dizisiyle çağrılabilir bir nesneyi (örn. Bir işlev) çağırır:
call ::= primary "(" [argument_list [","] | comprehension] ")"
Sadece liste için değil, herhangi bir isim için de aynı şeyi yaptığını görebiliriz:
>>> 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
İçin []
Python baytkodu düzeyinde hiçbir işlev çağrı var:
>>> dis.dis('[]')
1 0 BUILD_LIST 0
2 RETURN_VALUE
Sadece bayt kodu düzeyinde arama veya arama yapmadan listeyi oluşturmaya devam eder.
Sonuç
Biz gösterdik list
kapsam kuralları kullanarak kullanıcı kodu ile müdahale edebilecekleri ve bu list()
daha sonra çağrılabilir için görünüyor ve onu çağırır.
Oysa []
bir liste ekranı ya da bir değişmezdir ve bu nedenle ad arama ve işlev çağrısından kaçınır.
()
ve''
sadece boş olmadıkları için değişmezler ve bu nedenle onları tekil yapmak kolay bir kazançtır; onlar bile sadece boş için singleton yüklemek, yeni nesneler oluşturmak değiltuple
/ 'str
. Teknik olarak bir uygulama ayrıntı, ama onlar niye anlamakta zorlanıyor olmazdı boş önbelleğetuple
/str
performans nedenleriyle. Yani bir hisse senedi hazırlığı hakkındaki sezginiz[]
ve{}
geri dönüşünüz yanlıştı, ama()
ve için geçerli''
.