Apa sintaksis idiomatik untuk mengawali ke daftar python pendek?
Anda biasanya tidak ingin berulang-ulang menambahkan daftar ke dalam Python.
Jika pendek , dan Anda tidak sering melakukannya ... maka baiklah.
list.insert
The list.insert
dapat digunakan dengan cara ini.
list.insert(0, x)
Tapi ini tidak efisien, karena dalam Python, a list
adalah array dari pointer, dan Python sekarang harus mengambil setiap pointer dalam daftar dan memindahkannya ke bawah dengan satu untuk memasukkan pointer ke objek Anda di slot pertama, jadi ini benar-benar hanya efisien untuk daftar yang agak pendek, seperti yang Anda minta.
Berikut cuplikan dari sumber CPython tempat ini diterapkan - dan seperti yang Anda lihat, kita mulai dari akhir array dan memindahkan semuanya ke bawah satu per setiap penyisipan:
for (i = n; --i >= where; )
items[i+1] = items[i];
Jika Anda menginginkan sebuah wadah / daftar yang efisien dalam elemen-elemen yang saling bergantung, Anda menginginkan daftar yang ditautkan. Python memiliki daftar tertaut ganda, yang dapat menyisipkan di awal dan akhir dengan cepat - ini disebut a deque
.
deque.appendleft
A collections.deque
memiliki banyak metode daftar. list.sort
adalah pengecualian, membuat deque
Liskov pasti tidak sepenuhnya dapat diganti list
.
>>> set(dir(list)) - set(dir(deque))
{'sort'}
Ini deque
juga memiliki appendleft
metode (dan juga popleft
). Ini deque
adalah antrian dengan ujung ganda dan daftar yang terhubung ganda - tidak peduli panjangnya, selalu dibutuhkan jumlah waktu yang sama untuk menyiapkan sesuatu. Dalam notasi O besar, O (1) versus O (n) waktu untuk daftar. Inilah penggunaannya:
>>> import collections
>>> d = collections.deque('1234')
>>> d
deque(['1', '2', '3', '4'])
>>> d.appendleft('0')
>>> d
deque(['0', '1', '2', '3', '4'])
deque.extendleft
Juga relevan adalah metode deque extendleft
, yang secara iteratif menambahkan:
>>> from collections import deque
>>> d2 = deque('def')
>>> d2.extendleft('cba')
>>> d2
deque(['a', 'b', 'c', 'd', 'e', 'f'])
Perhatikan bahwa setiap elemen akan ditambahkan satu per satu, sehingga secara efektif membalik urutannya.
Penampilan dari list
versusdeque
Pertama kita atur dengan beberapa iterative prepending:
import timeit
from collections import deque
def list_insert_0():
l = []
for i in range(20):
l.insert(0, i)
def list_slice_insert():
l = []
for i in range(20):
l[:0] = [i] # semantically same as list.insert(0, i)
def list_add():
l = []
for i in range(20):
l = [i] + l # caveat: new list each time
def deque_appendleft():
d = deque()
for i in range(20):
d.appendleft(i) # semantically same as list.insert(0, i)
def deque_extendleft():
d = deque()
d.extendleft(range(20)) # semantically same as deque_appendleft above
dan kinerja:
>>> min(timeit.repeat(list_insert_0))
2.8267281929729506
>>> min(timeit.repeat(list_slice_insert))
2.5210217320127413
>>> min(timeit.repeat(list_add))
2.0641671380144544
>>> min(timeit.repeat(deque_appendleft))
1.5863927800091915
>>> min(timeit.repeat(deque_extendleft))
0.5352169770048931
Deque jauh lebih cepat. Seiring bertambahnya daftar, saya berharap deque akan tampil lebih baik. Jika Anda dapat menggunakan deque, extendleft
Anda mungkin akan mendapatkan kinerja terbaik dengan cara itu.