2016-05-24 11 views
7

aşağıdaki pasajı oluşturun ve her döngü sabitler listesini, havai bu ima (küçük de olsa) veya liste oluşturulduktan sonra ne olursa olsun üstlenmeden yok edecek mi? Ben mevcut olduğu ve ortak CPython uygulaması hakkında, Python "standart" Böyle biri ikisi hakkında soruyorumHer geçişte oluşturulmuş/silinmiş bir döngüde kullanılan sabit bir liste var mı?

for i in <some-type-of-iterable>: 
    if i in [1,3,5,18,3457,40567]: 
     print(i) 

.
Ben bu örnek yapmacık olduğunu farkındayım, hem de o CPython saçma kullanılarak performansı hakkında endişe çalışıyorum, ama sadece merak ediyorum.

+2

Bu gibi sorular ne yapılır? –

+0

Cevap "hayır" gibi görünüyor. – Jasper

cevap

2

Python 3.5 ile başka örnek, liste, her yineleme için oluşturulur.

>>> import dis 
>>> def func(): 
... for i in iterable: 
... for j in [1,2,3]: 
... print(i+j) 
... 
>>> dis.dis(func) 
    2   0 SETUP_LOOP    54 (to 57) 
       3 LOAD_GLOBAL    0 (iterable) 
       6 GET_ITER 
     >> 7 FOR_ITER    46 (to 56) 
      10 STORE_FAST    0 (i) 

    3   13 SETUP_LOOP    37 (to 53)  
      16 LOAD_CONST    1 (1)  # building list 
      19 LOAD_CONST    2 (2) 
      22 LOAD_CONST    3 (3) 
      25 BUILD_LIST    3 
      28 GET_ITER 
     >> 29 FOR_ITER    20 (to 52) # inner loop body begin 
      32 STORE_FAST    1 (j) 

    4   35 LOAD_GLOBAL    1 (print) 
      38 LOAD_FAST    0 (i) 
      41 LOAD_FAST    1 (j) 
      44 BINARY_ADD 
      45 CALL_FUNCTION   1 (1 positional, 0 keyword pair) 
      48 POP_TOP 
      49 JUMP_ABSOLUTE   29   # inner loop body end 
     >> 52 POP_BLOCK 
     >> 53 JUMP_ABSOLUTE   7   # outer loop end, 
               # jumping back before list creation 
     >> 56 POP_BLOCK 
     >> 57 LOAD_CONST    0 (None) 
      60 RETURN_VALUE 
+0

Sadece hangi listeyi bir kez oluşturuyorsunuz? Ben python bayt kodu okuma konusunda uzman değilim, ama iç listesi ('[4,5,6]') JUMP_ABSOLUTE nedeniyle 3 kez (her bir 'a' için bir kez) inşa edilecek gibi görünüyor 16'ndan önce, ikinci SETUP_LOOP', 'BUILD_LIST', vb. Önce geri koyarsınız ... – mgilson

+0

Haklısınız. Sabit ve güncel örnek. – Jasper

+0

Bahse girerim python2.7'nin de aynı performansa sahip olması gerekirdi ... ... ancak neden BUILD_LIST'ı neden optimize etmediklerini bilmiyorum. Bu listeye bir referans alacağınızı hiç düşünemiyorum - yinelemek için "sürekli" bir listeyi içeren bir döngü, gözden kaçan nadir bir vaka mıdır? – mgilson

3

Bu piton uygulanması ve sürümü ve nasıl "sabit listeler" kullanılır bağlıdır. 16 LOAD_CONST 4 ((1, 3, 5))

Python'un gözetleme deliği iyileştirici dönmüş: cevap if ifadesinin durumda liste sadece bir kez oluşturulduktan olmasıdır sevdiği örnek ile Cpython2.7.10 günü, o

>>> def foo(): 
... for i in iterable: 
...  if i in [1, 3, 5]: 
...  print(i) 
... 
>>> import dis 
>>> dis.dis(foo) 
    2   0 SETUP_LOOP    34 (to 37) 
       3 LOAD_GLOBAL    0 (iterable) 
       6 GET_ITER    
     >> 7 FOR_ITER    26 (to 36) 
      10 STORE_FAST    0 (i) 

    3   13 LOAD_FAST    0 (i) 
      16 LOAD_CONST    4 ((1, 3, 5)) 
      19 COMPARE_OP    6 (in) 
      22 POP_JUMP_IF_FALSE  7 

    4   25 LOAD_FAST    0 (i) 
      28 PRINT_ITEM   
      29 PRINT_NEWLINE  
      30 JUMP_ABSOLUTE   7 
      33 JUMP_ABSOLUTE   7 
     >> 36 POP_BLOCK   
     >> 37 LOAD_CONST    0 (None) 
      40 RETURN_VALUE   

Bildirim ... görünüyor listemize bir tuple (teşekkürler python!) ve bir sabit olarak saklanır. Gözetleme deliği optimize edicisinin, programcıların listeye bir gönderme yapmanın kesinlikle bir yolu olmadığını (eğer listeyi değiştirebilir ve kodun anlamını değiştirebilirseniz) bilirseniz, bu dönüşümleri yalnızca nesneler üzerinde yapabilir. Bildiğim kadarıyla farkındayım, onlar sadece bir in operatörün ÜSÖ tamamen sabitler oluşan? Elde edilen list, set sayılların bu optimizasyon yapmak. Farkında olmadığım başka durumlar da olabilir (dis.dis, bu optimizasyonları bulmak için arkadaşınızdır).

Yukarıda bahsettim, ancak python'un daha yeni sürümlerinde set-literal'lerle aynı şeyi yapabilirsiniz (python3.2 + 'da set sabit frozenset'a dönüştürülür). fayda set/frozensetlist/tuple göre ortalama olarak daha hızlı üyelik test olması vardır.

İlgili konular