Şunlar olmadan aşağıdakileri yapmak mümkün mü i
?
for i in range(some_number):
# do something
Sadece bir şeyi N kez yapmak istiyorsanız ve yineleyiciye ihtiyacınız yoksa.
Şunlar olmadan aşağıdakileri yapmak mümkün mü i
?
for i in range(some_number):
# do something
Sadece bir şeyi N kez yapmak istiyorsanız ve yineleyiciye ihtiyacınız yoksa.
Yanıtlar:
Kafamın üstünden, hayır.
Bence yapabileceğiniz en iyi şey şöyle:
def loop(f,n):
for i in xrange(n): f()
loop(lambda: <insert expression here>, 5)
Ama bence ekstra i
değişkenle yaşayabilirsin .
İşte _
gerçekte sadece başka bir değişken olan değişkeni kullanma seçeneği .
for _ in range(n):
do_something()
_
Etkileşimli bir python oturumunda döndürülen son sonucun atandığını unutmayın :
>>> 1+2
3
>>> _
3
Bu nedenle, bu şekilde kullanmam. Ryan'ın belirttiği gibi bir deyimin farkında değilim. Tercümanı bozabilir.
>>> for _ in xrange(10): pass
...
>>> _
9
>>> 1+2
3
>>> _
9
Python dilbilgisine göre , kabul edilebilir bir değişken adıdır:
identifier ::= (letter|"_") (letter | digit | "_")*
_
, dikkate alınmaması gerektiğini netleştirir. Bunu yapmanın bir anlamı olmadığını söylemek, kodunuzu yorumlamanın bir anlamı olmadığını söylemek gibidir - çünkü yine de aynısını yapar.
Arıyor olabilirsiniz
for _ in itertools.repeat(None, times): ...
bu times
Python kez tekrarlamak için en hızlı yoldur .
_'İ kullanmanızı öneren herkesin söylemediği şey, _'nin gettext işlevlerinden birine kısayol olarak kullanılmasıdır , bu nedenle yazılımınızın birden fazla dilde kullanılabilir olmasını istiyorsanız, bunu kullanmaktan kaçınmalısınız. başka amaçlar için.
import gettext
gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print _('This is a translatable string.')
_
korkunç bir fikir gibi gözüküyor, onunla çelişmem.
İşte veri modelini ( Py3 bağlantısı ) kullanan (kötüye kullanma?) Rastgele bir fikir .
class Counter(object):
def __init__(self, val):
self.val = val
def __nonzero__(self):
self.val -= 1
return self.val >= 0
__bool__ = __nonzero__ # Alias to Py3 name to make code work unchanged on Py2 and Py3
x = Counter(5)
while x:
# Do something
pass
Standart kütüphanelerde böyle bir şey var mı acaba?
__nonzero__
Yan etkiler gibi bir yönteme sahip olmak korkunç bir fikir.
__call__
yerine kullanırdım. while x():
yazmak o kadar zor değil.
Counter
; elbette, ayrılmış değil veya yerleşik kapsamda, ama collections.Counter
bir şeydir ve aynı isimde bir sınıf yapmak sürdürücü kafa karışıklığı riskine neden olur (bu zaten bunu riske atmaz).
Gettext ile ad çakışmasını önlemek için _11 (veya herhangi bir sayı veya başka bir geçersiz tanımlayıcı) kullanabilirsiniz. Alt çizgi + geçersiz tanımlayıcıyı her kullandığınızda, döngü için kullanılabilecek bir sahte ad alırsınız.
Yanıt, yineleyiciyi kullanmayla ilgili yaşadığınız soruna bağlı olabilir mi? olabilir
i = 100
while i:
print i
i-=1
veya
def loop(N, doSomething):
if not N:
return
print doSomething(N)
loop(N-1, doSomething)
loop(100, lambda a:a)
ama açıkçası böyle yaklaşımları kullanmanın bir anlamı yok
sys.getrecursionlimit()
(bu, düşük dörde bir yerde varsayılan değerdir) basamaklı aralık (CPython); kullanmak sys.setrecursionlimit
sınırı yükseltir, ancak sonunda C yığını sınırına ulaşırsınız ve yorumlayıcı bir yığın taşmasıyla ölür (sadece iyi bir RuntimeError
/ değil RecursionError
).
t=0
for _ in range(10):
print t
t = t+1
ÇIKTI:
0
1
2
3
4
5
6
7
8
9
Gereksiz bir sayaç yerine, artık gereksiz bir listeniz var. En iyi çözüm, sözdizimi denetleyicilerine değişkeni kullanmadığınızı bildiğinizi söyleyen "_" ile başlayan bir değişken kullanmaktır.
x = range(5)
while x:
x.pop()
print "Work!"
Genellikle yukarıda verilen çözümlere katılıyorum. Yani:
for
-Loop'ta (2 ve daha fazla satır)while
sayaç (3 ve daha fazla satır)__nonzero__
Uygulama ile özel bir sınıf bildirme (çok daha fazla satır)Biri bir nesneyi # 3'teki gibi tanımlayacaksa , anahtar kelimeyle protokolü uygulamanızı veya contextlib'i uygulamanızı öneririm .
Ayrıca başka bir çözüm öneriyorum. 3 astarlıdır ve üstün zerafet değildir, ancak itertools paketini kullanır ve bu nedenle ilgi çekici olabilir.
from itertools import (chain, repeat)
times = chain(repeat(True, 2), repeat(False))
while next(times):
print 'do stuff!'
Bu örnekte 2 , döngüyü yineleme sayısıdır. zincir iki tekrar yineleyiciyi sarıyor, ilki sınırlı ama ikincisi sonsuz. Bunların gerçek yineleyici nesneler olduğunu unutmayın, bu nedenle sonsuz bellek gerektirmezler. Açıkçası bu çözüm # 1'den çok daha yavaştır . Bir fonksiyonun parçası olarak yazılmadığı sürece times değişkeni için temizleme gerekebilir .
chain
gereksizdir, times = repeat(True, 2); while next(times, False):
aynı şeyi yapar.
Aşağıdakilerle biraz eğlendik, paylaşmak ilginç:
class RepeatFunction:
def __init__(self,n=1): self.n = n
def __call__(self,Func):
for i in xrange(self.n):
Func()
return Func
#----usage
k = 0
@RepeatFunction(7) #decorator for repeating function
def Job():
global k
print k
k += 1
print '---------'
Job()
Sonuçlar:
0
1
2
3
4
5
6
---------
7
Eğer do_something
basit bir fonksiyonudur veya birine basit sarılmış olabilir map()
kutu do_something
range(some_number)
süreleri:
# Py2 version - map is eager, so it can be used alone
map(do_something, xrange(some_number))
# Py3 version - map is lazy, so it must be consumed to do the work at all;
# wrapping in list() would be equivalent to Py2, but if you don't use the return
# value, it's wastefully creating a temporary, possibly huge, list of junk.
# collections.deque with maxlen 0 can efficiently run a generator to exhaustion without
# storing any of the results; the itertools consume recipe uses it for that purpose.
from collections import deque
deque(map(do_something, range(some_number)), 0)
Argümanları iletmek do_something
istiyorsanız, itertools repeatfunc
tarifinin iyi okuduğunu da görebilirsiniz:
Aynı argümanları iletmek için:
from collections import deque
from itertools import repeat, starmap
args = (..., my args here, ...)
# Same as Py3 map above, you must consume starmap (it's a lazy generator, even on Py2)
deque(starmap(do_something, repeat(args, some_number)), 0)
Farklı argümanlar iletmek için:
argses = [(1, 2), (3, 4), ...]
deque(starmap(do_something, argses), 0)
Eğer varsa , gerçekten bir isim ile bir şeyler koyarak (bir yineleme OP olarak değişken veya istenmeyen listesi veya zamanın gerçek istediği miktarda dönen istenmeyen jeneratör ya) Eğer gerçekten istiyorsa bunu yapabileceğini kaçınmak istiyorum:
for type('', (), {}).x in range(somenumber):
dosomething()
Kullanılan hile, type('', (), {})
boş ada sahip bir sınıfla sonuçlanan anonim bir sınıf oluşturmaktır , ancak yerel veya global ad alanına eklenmediğini (boş olmayan bir ad sağlansa bile). Daha sonra bu sınıfın bir üyesini, üyesi olduğu sınıfa erişilemediğinden erişilemeyen yineleme değişkeni olarak kullanırsınız.
#Return first n items of the iterable as a list
list(itertools.islice(iterable, n))
Ne dersin:
while range(some_number):
#do something
range(some_number)
her zaman doğrudur , bu sonsuz bir döngü !
some_number
küçük veya eşitse 0
, sonsuz değildir, asla çalışmaz. :-) Ve sonsuz bir döngü için (özellikle Py2'de) oldukça verimsizdir, çünkü her test için taze list
(Py2) veya range
nesne (Py3) oluşturur (tercümanın bakış açısından sabit değildir, yüklemesi gerekir range
ve some_number
her döngüyü arayın range
, ardından sonucu test edin).