2015-09-29 14 views
6

मुझे दो मानों के बीच लूप करना है, जहां कभी-कभी पहला मान कम होता है कि दूसरा और कुछ अन्य बार पहले दूसरे से बड़ा होता है (मैं ग्रिड के अंदर दो कोशिकाओं पर काम कर रहा हूं और पहला सेल दूसरे या वाइसवर्सा के बाईं ओर हो सकता है)।लूप बढ़ने या घटने के लिए पाइथन

step = 1 
if y<x: 
    step = -1 
for n in range(x,y,step): 
    pass 

वहाँ अधिक यह प्राप्त करने के लिए pythonic कुछ है:

अजगर के साथ मैं अगर पाश के लिए एक कम करने के लिए या अपने मूल्यों को बढ़ाने के लिए है, लेकिन नतीजा यह है कि जैसे कुछ है निर्दिष्ट कर सकते हैं? मैं अजगर 2.7 का उपयोग कर रहा हूं लेकिन पाइथन 3 पर जा रहा हूं यह एक अच्छा मुद्दा नहीं होगा।

+0

आप बस ऐसा कर सकते हैं: 'एन में सीमा के लिए (x, y, -1 अगर y

+2

जैसा ही है नोट करें कि '-1' के रूप में चरण का उपयोग छोटे से अधिक मूल्य से लूपिंग जैसा नहीं है! –

+0

@tobias_k इसे हाइलाइट करने के लिए धन्यवाद: आपने मेरे कोड में एक बग देखा! :-) –

उत्तर

8

ध्यान दें कि step=-1 का उपयोग कर नहीं बड़ा मूल्य के लिए छोटे से एक सीमा के रूप में ही है!

>>> range(3, 7, 1) 
[3, 4, 5, 6] 
>>> range(7, 3, -1) 
[7, 6, 5, 4] 

पहला वाला 3 से 6 है, बाद वाला 4 से 7 तक है।

>>> step = +1 if x < y else -1 # or use that 'or' expression 
>>> range(x, y + step, step) 
[7, 6, 5, 4, 3] 
:

>>> x, y = 7, 3 
>>> range(x, y, x < y or -1) 
[7, 6, 5, 4] 

तुम दोनों लोअर और अपर सूचकांक में शामिल करना चाहते हैं, तो आप to सूचकांक ऑफसेट करने के लिए है:

हैं कि अभी भी तुम क्या चाहते हो, एक और तरीका or उपयोग करने के लिए किया जाएगा

अन्यथा, आप मूल्यों पहले सॉर्ट सकता है, या तो min और max या sorted का उपयोग कर:

>>> x, y = sorted((x, y)) 
>>> range(x, y) 
[3, 4, 5, 6] 

या एक लाइन में: range(*sorted((x, y))) (हालांकि मुझे नहीं लगता कि यह बहुत ही पढ़ी जा सकती है)


मैं कुछ समय विश्लेषण, 1000 यादृच्छिक x, y जोड़े (प्रत्येक विधि के लिए एक ही जोड़े) आदेश देने किया:

  • x, y = sorted((x, y)) - 1000 जोड़े
  • के लिए> ~ 235μs -> ~ 1000 जोड़े
  • x, y = min(x, y), max(x, y) के लिए 305μs x, y = (x, y) if x < y else (y, x) -> ~ 1000 जोड़े

तो त्रिगुट ऑपरेटर सबसे तेज है के लिए 75μs, लेकिन ज्यादातर मामलों में यह शायद चाहिए ज्यादा बात नहीं, (रेंज आदि बनाने) कोड के बाकी की तुलना में

+0

से अधिक होता है, आप 'रेंज (* ((x, y) का उपयोग कर सकते हैं यदि x martineau

+0

@ मार्टिनौ आह, हाँ, यह क्रमबद्ध और न्यूनतम/अधिकतम के अलावा एक और संभावना है। यह तय करना आसान नहीं है कि कम से कम भयानक है ... IMHO समझना/विश्लेषण करना थोड़ा मुश्किल है, लेकिन प्रदर्शन-परिप्रेक्ष्य से, आपका शायद सबसे तेज़ है, लेकिन यह केवल प्रासंगिक होना चाहिए यदि यह वास्तव में वास्तव में निष्पादित होता है। –

+0

'क्रमबद्ध()' निश्चित रूप से सबसे अधिक पठनीय और संभवतः 99.9% ठीक है। यह सी में मेरी पृष्ठभूमि है जो मुझे दो वस्तुओं को क्रमबद्ध करने के लिए फ़ंक्शन को कॉल करने से बचने के लिए टर्नरी एक्सप्रेशन के संदर्भ में सोचने के लिए प्रेरित करती है। – martineau

4

मुझे लगता है कि आप कुछ इस तरह कर सकता है:

for n in xrange(min(x,y), max(x,y)): 

आपका रास्ता पहले से ही काफी pythonic है;)

संपादित करें: छोटा रास्ता सुझाव है @ wap26 द्वारा:

for n in xrange(*sorted((x,y))): 
+1

इंडेक्स का सेट सही है, लेकिन दिशा हमेशा क्रम में बढ़ रही है। – wap26

+1

थोड़ा अधिक कॉम्पैक्ट: 'xrange (* क्रमबद्ध ((x, y))) – wap26

+0

मैं अस्पष्ट प्रश्न में संशोधन करूंगा। 'मुझे दो मानों के बीच लूप करना है, जहां कभी-कभी पहला मान कम होता है कि दूसरा और कुछ अन्य बार पहले दूसरे – Cyrbil

1

Doesn अपने कोड से बहुत अलग नहीं है, लेकिन आप step

की गणना करने के लिए इसका उपयोग कर सकते हैं

उदाहरण के लिए:

In [10]: x,y = 5,10 

In [11]: range(x,y,(y-x)/abs(x-y)) 
Out[11]: [5, 6, 7, 8, 9] 

In [12]: x,y = 10,5 

In [13]: range(x,y,(y-x)/abs(x-y)) 
Out[13]: [10, 9, 8, 7, 6] 
संबंधित मुद्दे