2010-11-24 18 views
56

Hangisi daha pythonic?Bir Süreci X Süresini Çalıştırmak İçin Daha Fazla Pythonik Yol

döngü sırasında:

for i in range(50): 
    print "Some thing" 

Düzenleme:: döngü için

count = 0 
while count < 50: 
    print "Some thing" 
    count = count + 1 

bu daha net olduğunu belirlemek cevap vermektedir, çünkü tekrarlamamak, vs nasıl olmadan bir dizi çalıştırmak için 'i' - en zarif olan

+7

Upvoting Aşağı oyları telafi etmek için: eğer Lionel bu soruyu sorarsa, diğerleri Aynı soruya sahip olmalı ve aşağıdaki cevaplar faydalı olacaktır. – EOL

+2

Terim "Pythonic" aşırı kullanılıyor. Bu "okunabilir" ve "kolayca anlaşılabilir" bir eşanlamlı. En azından Python'da. – darioo

+0

Olası çoğaltılabilir [Yineleme değişkeni olmadan aralık döngüsü için Python uygulamak mümkün mü?] (Http://stackoverflow.com/questions/818828/is-it-possible-to-implement-a-python-for- aralık-döngü-olmayan-yineleyici-değişken) –

cevap

72

:

for _ in range(50): 
    print "Some thing" 

Eğer i gerekmiyorsa. Python < 3'ü kullanırsanız ve döngüyü bir çok kez tekrarlamak istiyorsanız, tüm listeyi önceden oluşturmaya gerek olmadığından xrange kullanın.

+10

Olsa da, gettext çeviri fonksiyonuna eşlenmelidir. '_' değişkeni için –

+6

+1. Bu benim önerdiğim şeydi. – EOL

+0

Bu cevap için teşekkürler; Bu, for-loop'u kullanmamın ana sebebiydi çünkü "i" de kullanılmayan bir değişkeni vardı. – Lionel

1

olmakla birlikte Döngü içinde gerçekleşen efektler, kişisel olarak range() yaklaşımına gideceğim.

Döngü içinde çağırdığınız işlevlerin sonucunu önemsiyorsanız, liste anlaşması veya map yaklaşımına gidersiniz. Böyle bir şey: Şahsen

def f(n): 
    return n * n 

results = [f(i) for i in range(50)] 
# or using map: 
results = map(f, range(50)) 
+0

results = (f için i aralığında (50)) –

+1

results = itertools.imap (f, aralık (50)) –

+0

@ralu, yalnızca ihtiyacınız yoksa Yine de sonuçlara tekrarlı veya rastgele erişim. – aaronasterling

-6

Bir şeyi tekrarlamak için gerçekten pythonik bir yol yoktur.

harita: Ancak, daha iyi bir yoludur (lambda endeksi:) (do_something, xrange (10))

sonra dizini geçmesi gerekiyorsa:

harita (lambda endeksi: do_something (dizin), xrange (10))

Sonuçları bir koleksiyon olarak döndürdüğünü düşünün, böylece sonuçları toplamanız gerekiyorsa yardımcı olabilir.

+0

Bu sadece daha iyi değil (işlev çağrısı ek yükü, daha az bilinen lambda ifadeleri, bir listede kullanılmayan sonuçları toplama), 10 tekrar edilemez. –

+0

Evet, xrange (10) değil 10. Daha iyi olduğunu söyledim çünkü bir işlev yazmanıza ya da bir döngü oluşturmanıza gerek yok. Ancak, söylediğim gibi gerçek bir pythonic yolu yoktur. Kodu değiştirdim, teşekkürler. –

1

Python'un daha net ve özlü bir şekilde yaptığınız şeyleri iletmek için Python'un daha yüksek düzeydeki işlevini kullandığı için, döngü gerçekten daha çok seslendiricidir. Xrange ve vs bir aralıkta kullanılmayan bir i değişken atama, Verilog'un repeat ifadesi gibi bir ifadenin yokluğundan kaynaklanır. Menzil çözümüne sadık olmanın temel nedeni, diğer yolların daha karmaşık olmasıdır. Mesela: Eğer aktarmanız gerekir çünkü değil de bir fonksiyon ve daha karmaşık bilinen çünkü

from itertools import repeat 

for unused in repeat(None, 10): 
    del unused # redundant and inefficient, the name is clear enough 
    print "This is run 10 times" 

yerine aralığının tekrarını kullanarak burada az açıktır. Referansa ihtiyacınız varsa ana stil kılavuzları PEP 20 - The Zen of Python ve PEP 8 - Style Guide for Python Code'dur.

Ayrıca, aralık aralığı sürümünün, language reference ve tutorial'da kullanılan açık bir örnek olduğunu da unutmayın, bu durumda değer kullanılır. Bu formun, bir C-stili döngü için genişlemeden daha tanıdık olması gerektiği anlamına gelir.

+0

Tekrarlanan şeyleri doğrudan kullanmak daha iyi olmaz mıydı, örneğin: 'tekrarlama için '(' Bu 10 kez çalıştırılır ', 10): print s' ?? – F1Rumors

+0

Kesinlikle! Fakat örnek koddaki baskı, sadece merkezi bir nesne bulunmayan tekrar eden kod bölümünün bir örneğiydi. –

-4

Peki ya?

while BoolIter(N, default=True, falseIndex=N-1): 
    print 'some thing' 

veya daha çirkin bir şekilde

:

for _ in BoolIter(N): 
    print 'doing somthing' 

veya içinden son kez yakalamak istiyorsanız:

for lastIteration in BoolIter(N, default=False, trueIndex=N-1): 
    if not lastIteration: 
     print 'still going' 
    else: 
     print 'last time' 

burada: amacıyla

class BoolIter(object): 

    def __init__(self, n, default=False, falseIndex=None, trueIndex=None, falseIndexes=[], trueIndexes=[], emitObject=False): 
     self.n = n 
     self.i = None 
     self._default = default 
     self._falseIndexes=set(falseIndexes) 
     self._trueIndexes=set(trueIndexes) 
     if falseIndex is not None: 
      self._falseIndexes.add(falseIndex) 
     if trueIndex is not None: 
      self._trueIndexes.add(trueIndex) 
     self._emitObject = emitObject 


    def __iter__(self): 
     return self 

    def next(self): 
     if self.i is None: 
      self.i = 0 
     else: 
      self.i += 1 
     if self.i == self.n: 
      raise StopIteration 
     if self._emitObject: 
      return self 
     else: 
      return self.__nonzero__() 

    def __nonzero__(self): 
     i = self.i 
     if i in self._trueIndexes: 
      return True 
     if i in self._falseIndexes: 
      return False 
     return self._default 

    def __bool__(self): 
     return self.__nonzero__() 
İlgili konular