क्या इसके बिना पालन करना संभव है i
?
for i in range(some_number):
# do something
यदि आप अभी कुछ समय एन की राशि करना चाहते हैं और पुनरावृत्ति की आवश्यकता नहीं है।
क्या इसके बिना पालन करना संभव है i
?
for i in range(some_number):
# do something
यदि आप अभी कुछ समय एन की राशि करना चाहते हैं और पुनरावृत्ति की आवश्यकता नहीं है।
जवाबों:
मेरे सिर के ऊपर से, नहीं।
मुझे लगता है कि सबसे अच्छा आप कुछ इस तरह कर सकते हैं:
def loop(f,n):
for i in xrange(n): f()
loop(lambda: <insert expression here>, 5)
लेकिन मुझे लगता है कि आप केवल अतिरिक्त i
चर के साथ रह सकते हैं ।
यहां _
चर का उपयोग करने का विकल्प है , जो वास्तव में, केवल एक और चर है।
for _ in range(n):
do_something()
ध्यान दें कि _
अंतिम परिणाम जो एक इंटरैक्टिव अजगर सत्र में लौटाया गया है:
>>> 1+2
3
>>> _
3
इस कारण से, मैं इसे इस तरीके से उपयोग नहीं करूंगा। मैं किसी भी मुहावरे से अनजान हूँ जैसा कि रेयान ने उल्लेख किया है। यह आपके दुभाषिया को गड़बड़ कर सकता है।
>>> for _ in xrange(10): pass
...
>>> _
9
>>> 1+2
3
>>> _
9
और अजगर व्याकरण के अनुसार , यह एक स्वीकार्य चर नाम है:
identifier ::= (letter|"_") (letter | digit | "_")*
_
से यह स्पष्ट हो जाता है कि इसे अनदेखा किया जाना चाहिए। यह कहना कि ऐसा करने का कोई मतलब नहीं है, यह कहने जैसा है कि आपके कोड पर टिप्पणी करने का कोई मतलब नहीं है - क्योंकि यह वैसे भी बिल्कुल वैसा ही करेगा।
आप ढूंढ रहे होंगे
for _ in itertools.repeat(None, times): ...
यह times
पायथन में समय को पुन: व्यवस्थित करने का सबसे तेज़ तरीका है ।
हर कोई जो आपको _ का उपयोग करने का सुझाव देता है, वह यह नहीं कहता है कि _ अक्सर गेटटेक्स्ट कार्यों में से एक के लिए एक शॉर्टकट के रूप में उपयोग किया जाता है , इसलिए यदि आप चाहते हैं कि आपका सॉफ़्टवेयर एक से अधिक भाषाओं में उपलब्ध हो, तो आप इसका उपयोग करने से बचते हैं। अन्य उद्देश्यों के लिए।
import gettext
gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print _('This is a translatable string.')
_
एक भयानक विचार की तरह लगता है, मैं इसके साथ विरोध नहीं करूंगा।
यहां एक यादृच्छिक विचार है जो डेटा मॉडल ( Py3 लिंक ) का उपयोग (दुरुपयोग) करता है ।
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
मुझे आश्चर्य है कि क्या मानक पुस्तकालयों में ऐसा कुछ है?
__nonzero__
साइड-इफेक्ट के साथ एक विधि होना एक भयानक विचार है।
__call__
इसके बजाय प्रयोग करेंगे । while x():
लिखने के लिए इतना कठिन नहीं है।
Counter
; निश्चित रूप से, यह आरक्षित या बिल्ट-इन स्कोप में नहीं है, बल्कि collections.Counter
एक चीज़ है , और एक ही नाम के जोखिम को बनाए रखने वाला एक वर्ग बना हुआ है भ्रम (यह नहीं कि यह पहले से ही जोखिम में नहीं है)।
गेटटेक्स्ट के साथ नाम-विभाजन को रोकने के लिए आप _11 (या किसी भी संख्या या अन्य अमान्य पहचानकर्ता) का उपयोग कर सकते हैं। जब भी आप अंडरस्कोर + अमान्य पहचानकर्ता का उपयोग करते हैं तो आपको एक डमी नाम मिलता है जिसका उपयोग लूप के लिए किया जा सकता है।
हो सकता है कि इसका उत्तर इस बात पर निर्भर करेगा कि आपको पुनरावृत्ति का उपयोग करने में क्या समस्या है? उपयोग हो सकता है
i = 100
while i:
print i
i-=1
या
def loop(N, doSomething):
if not N:
return
print doSomething(N)
loop(N-1, doSomething)
loop(100, lambda a:a)
लेकिन स्पष्ट रूप से मैं इस तरह के दृष्टिकोण का उपयोग करने में कोई मतलब नहीं देखता
sys.getrecursionlimit()
(जो कि कम चार में कहीं भी चूक करता है) CPython पर अंक सीमा); उपयोग sys.setrecursionlimit
करने से सीमा बढ़ेगी, लेकिन अंततः आप सी स्टैक सीमा से टकराएंगे और दुभाषिया स्टैक ओवरफ्लो के साथ मर जाएगा (न कि केवल एक अच्छा RuntimeError
/ बढ़ाकर RecursionError
)।
t=0
for _ in range(10):
print t
t = t+1
उत्पादन:
0
1
2
3
4
5
6
7
8
9
एक अनावश्यक काउंटर के बजाय, अब आपके पास एक अनावश्यक सूची है। सबसे अच्छा समाधान एक चर का उपयोग करना है जो "_" से शुरू होता है, जो वाक्यविन्यास चेकर्स को बताता है कि आप जानते हैं कि आप चर का उपयोग नहीं कर रहे हैं।
x = range(5)
while x:
x.pop()
print "Work!"
मैं आम तौर पर ऊपर दिए गए समाधानों से सहमत हूं। इसके साथ नम:
for
-लूप (2 और अधिक पंक्तियों) मेंwhile
काउंटर को परिभाषित करना (3 और अधिक लाइनें)__nonzero__
कार्यान्वयन के साथ एक कस्टम वर्ग की घोषणा (कई और लाइनें)यदि कोई # 3 के रूप में एक वस्तु को परिभाषित करने के लिए है, तो मैं कीवर्ड के साथ प्रोटोकॉल को लागू करने या संदर्भ सूची को लागू करने की सिफारिश करूंगा ।
इसके अलावा मैं अभी तक एक और समाधान का प्रस्ताव है। यह एक 3 लाइनर है और सर्वोच्च लालित्य का नहीं है, लेकिन यह itertools पैकेज का उपयोग करता है और इस प्रकार एक ब्याज का हो सकता है।
from itertools import (chain, repeat)
times = chain(repeat(True, 2), repeat(False))
while next(times):
print 'do stuff!'
इन उदाहरणों में 2 लूप को पुनरावृत्त करने के लिए कई बार है। श्रृंखला दो पुनरावृत्तियों को लपेट रही है, पहला सीमित है लेकिन दूसरा अनंत है। याद रखें कि ये सत्य पुनरावृत्त वस्तुएं हैं, इसलिए उन्हें अनंत स्मृति की आवश्यकता नहीं है। जाहिर है यह बहुत धीमी है तो समाधान # 1 । जब तक किसी फ़ंक्शन के भाग के रूप में नहीं लिखा जाता है, तो उसे बार चर के लिए क्लीन अप की आवश्यकता हो सकती है ।
chain
अनावश्यक है, times = repeat(True, 2); while next(times, False):
एक ही बात करता है।
हमने निम्नलिखित के साथ कुछ मजेदार किया है, दिलचस्प है ताकि साझा करें:
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()
परिणाम:
0
1
2
3
4
5
6
---------
7
यदि do_something
एक सरल कार्य है या एक में लपेटा जा सकता है, तो एक सरल समय map()
हो सकता do_something
range(some_number)
है:
# 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)
यदि आप तर्कों को पारित करना चाहते हैं do_something
, तो आप यह भी जानrepeatfunc
सकते हैं कि इटर्लस नुस्खा अच्छी तरह से पढ़ता है:
एक ही तर्क पारित करने के लिए:
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)
विभिन्न तर्कों को पारित करने के लिए:
argses = [(1, 2), (3, 4), ...]
deque(starmap(do_something, argses), 0)
यदि आप वास्तव में किसी नाम के साथ कुछ डालने से बचना चाहते हैं (या तो ओपी में वैरिएबल वैरिएबल, या अवांछित सूची या अवांछित जनरेटर सही समय की वांछित राशि लौटाते हैं) तो आप इसे कर सकते हैं यदि आप वास्तव में चाहते थे:
for type('', (), {}).x in range(somenumber):
dosomething()
जिस ट्रिक का उपयोग किया जाता है, वह एक अनाम वर्ग बनाने के लिए है type('', (), {})
जिसका परिणाम खाली नाम के साथ एक वर्ग में होता है, लेकिन NB कि यह स्थानीय या वैश्विक नाम स्थान (भले ही कोई गैर-रिक्त नाम आपूर्ति की गई हो) में सम्मिलित नहीं है। फिर आप उस वर्ग के एक सदस्य का उपयोग करें जो कि परिवर्तनशील चर के रूप में अनुपलब्ध है क्योंकि यह जिस वर्ग का सदस्य है वह अप्राप्य है।
#Return first n items of the iterable as a list
list(itertools.islice(iterable, n))
Http://docs.python.org/2/library/itertools.html से लिया गया
व्हाट अबाउट:
while range(some_number):
#do something
range(some_number)
हमेशा सच होती है!
some_number
इससे कम या इसके बराबर है 0
, तो यह अनंत नहीं है, यह सिर्फ कभी नहीं चलता है। :-) और यह बजाय एक अनंत लूप (विशेष रूप से Py2 पर) के लिए अक्षम है, क्योंकि यह एक ताजा बनाता है list
(Py2) या range
प्रत्येक परीक्षा के लिए वस्तु (Py3) (यह देखने का दुभाषिया के दृष्टिकोण से एक निरंतर नहीं है, यह लोड करने के लिए है range
और some_number
हर लूप, कॉल करें range
, फिर परिणाम का परीक्षण करें)।