koddla

Yazılımcıları bilgi ile güçlendirir.

Python’da bir listenin boş olduğunu nasıl anlarız?

Örneğin, aşağıdaki gibi bir listemiz olsa, bu listenin boş olup olmadığını nasıl kontrol ederiz?

a = []

Kısa Cevap:

Listeyi bir boole bağlamına yerleştirin (örneğin, bir if veya while deyimiyle), sonuç False ise boş, True ise doludur.

if not a:                           
    print('a boş bir liste')

PEP 8

Python’un standart kitaplığındaki Python kodu için resmi Python stil kılavuzu olan PEP 8 şunu söylüyor:

Dizilerin (dizeler, listeler, diziler) False olduğu gerçeğini kullanın.

Yes: if not seq:
     if seq:

No: if len(seq):
    if not len(seq):

Standart kitaplık kodunun mümkün olduğunca performanslı ve doğru olmasını beklemeliyiz. Ama neden durum bu ve neden bu rehberliğe ihtiyacımız var?

Açıklama

Python’da yeni olan deneyimli programcılardan sık sık böyle kodlar görebilirsiniz:

if len(a) == 0:                     # Bunu yapmayın
    print('a boş bir liste')

Ve tembel dil kullanıcıları da bunu yapmak isteyebilir:

if a == []:                         # Bunu yapmayın
    print('a boş bir liste')

Bunlar başka dillerde doğru olabilir. Ve Python’da da anlamsal olarak doğrudur.

Ancak pythonik olmadığını düşünüyoruz, çünkü Python semantik bir şekilde doğrudan boole zorlaması yoluyla liste nesnesini destekliyor.

Pythonik yöntemi kullanmak genellikle performansta karşılığını verir

Karşılığını veriyor mu? (Eşdeğer bir işlemi gerçekleştirmek için daha az süre daha iyidir)

>>> import timeit
>>> min(timeit.repeat(lambda: len([]) == 0, repeat=100))
0.13775854044661884
>>> min(timeit.repeat(lambda: [] == [], repeat=100))
0.0984637276455409
>>> min(timeit.repeat(lambda: not [], repeat=100))
0.07878462291455435

Ölçek için, boş bir liste oluşturmanın ve döndürmenin maliyeti aşağıda:

>>> min(timeit.repeat(lambda: [], repeat=100))
0.07074015751817342

Yerleşik işlevle uzunluğun denetlendiği, veya boş bir listeye karşı kontrol edildiği yöntemlerin çok daha az performanslı olduğunu görüyoruz.

Neden?

len(a) == 0 kontrolü için:

İlk olarak Python len‘in varlığını kontrol etmek zorunda. 

Ardından işlevi çağırmalı, yüklemeli ve Python’da eşitlik karşılaştırmasını yapmalı.

>>> import dis
>>> dis.dis(lambda: len([]) == 0)
  1           0 LOAD_GLOBAL              0 (len)
              2 BUILD_LIST               0
              4 CALL_FUNCTION            1
              6 LOAD_CONST               1 (0)
              8 COMPARE_OP               2 (==)
             10 RETURN_VALUE

[] == [] için ise önce gereksiz bir liste oluşturması ve ardından yine Python’un sanal makinesinde karşılaştırma işlemini yapması gerekir

>>> dis.dis(lambda: [] == [])
  1           0 BUILD_LIST               0
              2 BUILD_LIST               0
              4 COMPARE_OP               2 (==)
              6 RETURN_VALUE

Listenin uzunluğu nesnenin üstbilgisinde önbelleğe kaydedildiğinden “Pythonik” yolu çok daha basit ve hızlı bir denetim olacaktır:

>>> dis.dis(lambda: not [])
  1           0 BUILD_LIST               0
              2 UNARY_NOT
              4 RETURN_VALUE

Bir yanıt yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Back to top