Diğerleri de belirtildiği gibi pop ve del şunlardır verilen dizinin bir öğeyi kaldırmak için etkili yollar. Ancak sadece tamamlama uğruna (aynı şey Python'da birçok yolla yapılabilir):
Dilimleri kullanma (bu, öğenin orijinal listeden kaldırılmasını sağlamaz):
(Ayrıca bu Python listesiyle çalışırken en az etkili yöntem olacaktır, ancak pop'u desteklemeyen, ancak a tanımlayan kullanıcı tanımlı nesnelerle çalışırken bu yararlı olabilir (ancak verimli değil, tekrar ediyorum) __getitem__
):
>>> a = [1, 2, 3, 4, 5, 6]
>>> index = 3 # Only positive index
>>> a = a[:index] + a[index+1 :]
# a is now [1, 2, 3, 5, 6]
Not: Bu yöntemin, pop
ve gibi yerdeki listeyi değiştirmediğini lütfen unutmayın del
. Bunun yerine, listelerin iki kopyasını oluşturur (biri başlangıçtan dizine kadar ancak onsuz ( a[:index]
) ve dizinden sonra son öğeye ( a[index+1:]
) kadar) ve her ikisini de ekleyerek yeni bir liste nesnesi oluşturur. Bu daha sonra list değişkenine ( a
) yeniden atanır . Bu nedenle, eski liste nesnesinin kaydı kaldırılır ve dolayısıyla çöp toplanır (orijinal liste nesnesine a dışında bir değişken tarafından başvurulmaması koşuluyla).
Bu, bu yöntemi çok verimsiz hale getirir ve ayrıca istenmeyen yan etkiler de üretebilir (özellikle diğer değişkenler değiştirilmemiş kalan orijinal liste nesnesini gösterdiğinde).
@MarkDickinson'a bunu işaret ettiği için teşekkürler ...
Bu Yığın Taşması yanıtı, dilimleme kavramını açıklar.
Ayrıca, bunun yalnızca pozitif endekslerle çalıştığını da unutmayın.
Nesnelerle birlikte kullanılırken, __getitem__
yöntemin tanımlanmış olması ve daha da önemlisi, __add__
her iki işlenenden öğeler içeren bir nesne döndürmek için yöntemin tanımlanmış olması gerekir.
Özünde, bu sınıf tanımı aşağıdaki gibi olan herhangi bir nesne ile çalışır:
class foo(object):
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return foo(self.items[index])
def __add__(self, right):
return foo( self.items + right.items )
Bu, list
hangi yöntem __getitem__
ve __add__
yöntemleri tanımlar .
Verimlilik açısından üç yolun karşılaştırılması:
Aşağıdakilerin önceden tanımlandığını varsayın:
a = range(10)
index = 3
del object[index]
yöntem:
Şimdiye kadar en verimli yöntem. Bir __del__
yöntemi tanımlayan tüm nesneler çalışır .
Sökme aşağıdaki gibidir:
Kod:
def del_method():
global a
global index
del a[index]
demontaj:
10 0 LOAD_GLOBAL 0 (a)
3 LOAD_GLOBAL 1 (index)
6 DELETE_SUBSCR # This is the line that deletes the item
7 LOAD_CONST 0 (None)
10 RETURN_VALUE
None
pop
yöntem:
Del yönteminden daha az verimlidir ve silinen öğeyi almanız gerektiğinde kullanılır.
Kod:
def pop_method():
global a
global index
a.pop(index)
demontaj:
17 0 LOAD_GLOBAL 0 (a)
3 LOAD_ATTR 1 (pop)
6 LOAD_GLOBAL 2 (index)
9 CALL_FUNCTION 1
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
Dilim ve ekleme yöntemi.
En az verimlidir.
Kod:
def slice_method():
global a
global index
a = a[:index] + a[index+1:]
demontaj:
24 0 LOAD_GLOBAL 0 (a)
3 LOAD_GLOBAL 1 (index)
6 SLICE+2
7 LOAD_GLOBAL 0 (a)
10 LOAD_GLOBAL 1 (index)
13 LOAD_CONST 1 (1)
16 BINARY_ADD
17 SLICE+1
18 BINARY_ADD
19 STORE_GLOBAL 0 (a)
22 LOAD_CONST 0 (None)
25 RETURN_VALUE
None
Not: Her üç sökme işleminde de temel olarak son iki satırı görmezden gelin return None
. Ayrıca ilk iki satır global değerleri a
ve index
.
O(n)
.deque()
her iki uçta da verimli işlemler sağlar ancak ortada O (1) yerleştirme / arama / silme sağlamaz.