SORU
28 NİSAN 2014, PAZARTESİ


Del kullanımı, kötü mü?

Ben genellikle nesneleri silmek için benim kod del kullanın:

>>> array = [4, 6, 7, 'hello', 8]
>>> del(array[array.index('hello')])
>>> array
[4, 6, 7, 8]
>>> 

Ama many people del kullanımı unpythonic olduğunu söylüyorlar duydum. del kötü uygulama kullanarak?

>>> array = [4, 6, 7, 'hello', 8]
>>> array[array.index('hello'):array.index('hello') 1] = ''
>>> array
[4, 6, 7, 8]
>>> 

Neden python aynı şeyi yapmanın birçok yolu vardır. Diğerlerine göre daha iyidir?

Seçenek 1: del

>>> arr = [5, 7, 2, 3]
>>> del(arr[1])
>>> arr
[5, 2, 3]
>>> 

Seçenek 2: list.remove()

>>> arr = [5, 7, 2, 3]
>>> arr.remove(7)
>>> arr
[5, 2, 3]
>>> 

Seçenek 3: list.pop()

>>> arr = [5, 7, 2, 3]
>>> arr.pop(1)
7
>>> arr
[5, 2, 3]
>>> 

Seçenek 4: kullanarak Dilimleme

>>> arr = [5, 7, 2, 3]
>>> arr[1:2] = ''
>>> arr
[5, 2, 3]
>>> 

Üzgünüm eğer bu soruyu görünüyor görüş tabanlı, ama arıyorum makul soruma cevap, ve ben eklemek ödül sonra 2 gün gitmem lazım, uygun bir cevap.

Düzenleme:

del nesnelerin bazı bölümlerini silmek için kullanmanın birçok alternatifler vardır beri, eşsiz faktörü del sol nesneleri tamamen kaldırmak için yeteneğidir:

>>> a = 'hello'
>>> b = a
>>> del(a)
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> b
'hello'
>>> 

Ancak, bunu kullanarak ne anlamı var 'tanımsız' nesneler?

Ayrıca, neden aşağıdaki kod her iki değişken değiştirme:

>>> a = []
>>> b = a
>>> a.append(9)
>>> a
[9]
>>> b
[9]
>>> 

Ama del deyimi de aynı etkiyi yapar değil mi?

>>> a = []
>>> b = a
>>> del(a)
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> b
[]
>>> 

CEVAP
28 NİSAN 2014, PAZARTESİ


Diğer cevaplar ver bir teknik bakış açısı (yani ne en iyi yolu değiştirmek için bir liste), ama ben söyleyebilirim, ben (çok) daha önemli sebebi, insanları düşündüren örneğin Dilimleme olduğundan değil değiştirmek orijinal liste.

Bu nedenle genellikle, bu liste bir yerden geldi. Değiştirirseniz, unknowningly böcekler başka bir yerde programda neden çok kötü ve zor tespit yan etkilere neden olabilir. Ya da eğer bir hatayı neden yok varsa bile, programın genel zor anlaşılması ve hakkında neden, ve hata ayıklama için yapacağız.

Örneğin, liste üreteçleri/jeneratör ifadeler asla "kaynak" liste geçirilen: . bu mutasyona o güzel

[x for x in lst if x != "foo"]  # creates a new list
(x for x in lst if x != "foo")  # creates a lazy filtered stream

Bu yeni bir liste oluşturduğu için tabii ki genellikle daha pahalı (bellek) hikmet sahibidir ama bu yaklaşım kullanan bir program matematiksel olarak saf ve yaklaşık bir sebep daha kolaydır. Ve tembel listeleri (jeneratörler ve jeneratör ifadeler), bellek yükü ortadan kalkacak ve hesaplamaları sadece isteğe bağlı olarak yürütülen; harika bir giriş için http://www.dabeaz.com/generators/ bkz. Ve program (http://programmers.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil) tasarlarken çok fazla optimizasyon düşünmelisin. Ayrıca, listeden bir öğeyi kaldırmak bağlantılı liste (list hangisi değil; liste, collections.deque bağlı değil) olmadığı sürece oldukça pahalıdır.


Aslında, yan etkisi ücretsiz ve fonksiyonlarıimmutable data structures temelini oluştururİşlevsel Programlamaçok güçlü bir programlama paradigma.

Ancak, belirli koşullarda, TAMAM değiştirmek için bir veri yapısı içinde yer (hatta FP, if the language allows it) gibi olunca, yerel olarak oluşturulan veya kopyalanan işlevi giriş:

def sorted(lst):
    ret = list(lst)  # make a copy
    # mutate ret
    return ret

— bu işlev görünüyor saf bir işlevi yok çünkü değil değiştirmek girişleri (ve de sadece bağlı bağımsız değişkenleri ve başka bir şey (yani yok (küresel) devlet), bir ihtiyaç için bir şey olmak Pure Function).

Ne yaptığınızı bildiğiniz sürece, del kötü anlamına gelir; ama çok dikkatli mutasyon veri herhangi bir tür kullanarak ve sadece. Her zaman muhtemelen daha az verimli ama daha doğru ve matematiksel olarak zarif bir kod ile başlayalım.

...ve öğrenmek 44**:)

S. S. del ayrıca yerel değişkenler Sil ve sık sık ilgili amaçlar GC ne için yararlı olan bellek nesneleri için başvurular böylece ortadan kaldırmak için kullanılabileceğini unutmayın.


İkinci sorunun cevabı:

Sorunuzun ikinci bölümü hakkındadel kaldırma nesneleri tamamen— bu durumda: aslında Python, hatta mümkünse söyle tercüman/VM kaldırmak bir nesneyi bellekten çünkü Python bir çöp toplama dil (Java, C#, Ruby, Haskell, vb.) ve çalışma zamanı karar verir ne kaldırmak ve zaman.

Bunun yerine, ne del böyle bir değişken sözlük bir anahtar veya liste öğesi (karşıt olarak) aradığında yapar:

del a

olduğunusadece(ya da küresel) yerel değişken kaldırırdeğildeğişken (Python her değişken içeriğini gösterici/bir referans içeriği kendisi tutar değil) puan. Yerli ve global başlık altında bir sözlük (locals() globals()), del a olarak saklanır bu yana, aslında, eşittir:

del locals()['a']

ya da bir küresel uygulandığında del globals()['a'].

eğer varsa:

a = []
b = a

bir liste yapmak, a bir başvuru depolamak ve daha sonra bu başvurunun bir kopyasını yapmak ve b olmadan kopyalama/içine listeyi kendisi nesne dokunmadan saklamak. Bu nedenle, bu iki arama bir etkiliyor ve aynı nesne:

a.append(1)
b.append(2)
 # the list will be [1, 2]

silme ise b b ne işaret dokunmakla ilgili

a = []
b = a
del b
# a is still untouched and points to a list

Ayrıca, hatta zaman sana haber del bir nesne özniteliği (örneğin del self.a), sen hala gerçekten değiştirmek sözlük self.__dict__ tıpkı senin gibi aslında değiştirme locals()/globals() yapmak del a.

P. S. olarak Sven Marcnah del locals()['a'] aslında doğru olan bir fonksiyon içinde yerel değişken a silmez olduğuna işaret etti. Bu muhtemelen locals() gerçek yerli bir kopyasını dönen kaynaklanmaktadır. Ancak, cevap genellikle hala geçerlidir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • george sarintzotis

    george sarin

    2 Aralık 2007
  • kimaliz

    kimaliz

    18 Temmuz 2006
  • technodromeband's channel

    technodromeb

    28 NİSAN 2011