2010-01-30 21 views
29
li = [0, 1, 2, 3] 

running = True 
while running: 
    for elem in li: 
     thiselem = elem 
     nextelem = li[li.index(elem)+1] 

जब यह पिछले तत्व तक पहुँच जाता है, एक IndexError उठाया है को दोहराते रहते है (जैसा कि किसी भी सूची, टपल, शब्दकोश, या स्ट्रिंग कि दोहराया है के लिए मामला है)। मैं वास्तव में उस बिंदु पर nextelem के बराबर li[0] के लिए चाहता हूं। इसका मेरा बोझिल समाधानअगले तत्व हो रही है, जबकि एक सूची

while running: 
    for elem in li: 
     thiselem = elem 
     nextelem = li[li.index(elem)-len(li)+1] # negative index 

क्या ऐसा करने का कोई बेहतर तरीका है?

+0

जबकि पाश बाहर छोड़ने पर विचार देता है। यह सवाल के लिए अप्रासंगिक लगता है। यदि यह प्रासंगिक है, तो क्यों समझाओ। –

+0

मैं अनिश्चित काल तक एक सूची के माध्यम से चक्र बनाना चाहता हूं, इसलिए समय/लूप संयोजन के लिए। क्षमा करें, उसको समझाया नहीं। –

+0

मुझे लगता है कि आप आदर्श रूप से अंत में बजाय चक्र के बीच में रुकने में सक्षम होना चाहते हैं? – Omnifarious

उत्तर

50

ध्यान के माध्यम से इस बारे में सोच करने के बाद, मुझे लगता है कि यह सबसे अच्छा तरीका है। यह आपको break का उपयोग किये बिना आसानी से बीच में उतरने देता है, जो मुझे लगता है कि महत्वपूर्ण है, और इसे न्यूनतम गणना की आवश्यकता है, इसलिए मुझे लगता है कि यह सबसे तेज़ है। यह भी आवश्यक नहीं है कि li एक सूची या टुपल हो। यह कोई इटरेटर हो सकता है।

from itertools import cycle 

li = [0, 1, 2, 3] 

running = True 
licycle = cycle(li) 
# Prime the pump 
nextelem = next(licycle) 
while running: 
    thiselem, nextelem = nextelem, next(licycle) 

मैं भावी पीढ़ी के लिए यहाँ अन्य समाधान जा रहा हूँ।

उस फैंसी इटरेटर सामान की सभी जगहें हैं, लेकिन यहां नहीं। % ऑपरेटर का प्रयोग करें।

li = [0, 1, 2, 3] 

running = True 
while running: 
    for idx, elem in enumerate(li): 
     thiselem = elem 
     nextelem = li[(idx + 1) % len(li)] 

अब, अगर आप एक सूची के माध्यम से चक्र असीम करने का इरादा है, तो बस ऐसा करते हैं:

li = [0, 1, 2, 3] 

running = True 
idx = 0 
while running: 
    thiselem = li[idx] 
    idx = (idx + 1) % len(li) 
    nextelem = li[idx] 

मुझे लगता है कि अन्य tee से जुड़े समाधान की तुलना में समझने के लिए आसान है, और शायद इसकी गति और भी। यदि आप सुनिश्चित हैं कि सूची आकार में नहीं बदलेगी, तो आप len(li) की एक प्रति को गिलहरी कर सकते हैं और इसका उपयोग कर सकते हैं।

यह आपको बाल्टी को फिर से नीचे आने के लिए इंतजार करने के बजाय बीच में फेरिस व्हील को आसानी से बंद करने देता है। अन्य समाधान (आपके सहित) की आवश्यकता है कि आप runningfor लूप के बीच में और फिर break देखें।

+1

+1 हाँ, यह भी सरल और प्रभावी है। उन समस्याओं के लिए इन अनावश्यक जटिल कार्यात्मक समाधानों की कोई आवश्यकता नहीं है जिनमें अत्यंत सरल प्रक्रियात्मक समाधान हैं। पायथन एक कार्यात्मक भाषा नहीं है! –

+0

@ मार्क बेयर्स, धन्यवाद! मुझे लगता है कि अगर सूची काफी छोटी है, तो मैंने काफी कार्यात्मक समाधान के लिए जगह बनाई है, और मैंने इसे जोड़ा। 'चलने 'के साथ पूरा बिट कार्यात्मक नहीं है, और इसे एक कार्यात्मक समाधान में shoehorn करने की कोशिश बदसूरत है। – Omnifarious

+0

@ मार्क बिअर्स: वहां, मुझे लगता है कि उत्तर इटारटोल का सबसे अच्छा उपयोग करता है, लेकिन एक बहुत ही सरल तरीके से। मुझे लगता है कि यह बहुत तेज है, और समझने में आसान है। – Omnifarious

9
while running: 
    for elem,next_elem in zip(li, li[1:]+[li[0]]): 
     ... 
+0

+1 सरल कभी-कभी सबसे अच्छा होता है। –

+0

यह मेरा दूसरा पसंदीदा है, मेरे बाद।:-) सरल सबसे अच्छा है, लेकिन यदि सूची पूरी तरह से बड़ी है, तो इससे इसकी दो प्रतियां बनती हैं। – Omnifarious

7

आप एक जोड़ो में चक्रीय इटरेटर का उपयोग कर सकते हैं:

from itertools import izip, cycle, tee 

def pairwise(seq): 
    a, b = tee(seq) 
    next(b) 
    return izip(a, b) 

for elem, next_elem in pairwise(cycle(li)): 
    ... 
+0

यह अच्छा है। इसमें थोड़ी लूप और लूप के लिए एक संक्षिप्त लूप में शामिल होता है, जो लगातार सूची में आसन्न जोड़े पर फिर से चलाता है, और अंत में लपेटता है। Pairwise का उपयोग करने के लिए –

+0

+1 - एक अनौपचारिक लाइब्रेरी फ़ंक्शन जो केवल Itertools के लिए प्रलेखन में मौजूद है। इसलिए जब आप इसे आयात नहीं कर सकते हैं, तो यह काम करने के लिए जाना जाता है। –

+0

मुझे लगता है कि लूप के अंदर दौड़ने के लिए परीक्षण को अस्पष्ट करना और 'ब्रेक' के उपयोग की आवश्यकता है, यह इतना अच्छा विचार नहीं है। – Omnifarious

3
while running: 
    lenli = len(li) 
    for i, elem in enumerate(li): 
     thiselem = elem 
     nextelem = li[(i+1)%lenli] 
1

एक नहीं बल्कि अलग तरह से इस को हल करने के:

li = [0,1,2,3] 

    for i in range(len(li)): 

     if i < len(li)-1: 

      # until end is reached 
      print 'this', li[i] 
      print 'next', li[i+1] 

     else: 

      # end 
      print 'this', li[i] 
3

अजगर में ज़िप विधि का उपयोग करें। इस समारोह tuples की एक सूची है, जहां मैं-वें टपल तर्क दृश्यों में से प्रत्येक से आई-वें तत्व शामिल है या iterables

while running: 
     for thiselem,nextelem in zip(li, li[1 : ] + li[ : 1]): 
      #Do whatever you want with thiselem and nextelem   
-4
c = [ 1, 2, 3, 4 ] 

i = int(raw_input(">")) 

if i < 4: 
    print i + 1 
else: 
    print -1 
+1

क्या आप समझा सकते हैं कि आपका कोड क्या कर रहा है और यह क्यों काम करता है? – DVK

+0

आपका उत्तर इस प्रश्न के लिए कुछ भी नया नहीं जोड़ता है, जो 6 साल पहले से है और पहले से ही एक विस्तृत और स्वीकृत उत्तर है (और यह भी सही जवाब नहीं है) – DeepSpace

0
 li = [0, 1, 2, 3] 
     for elem in li: 
      if (li.index(elem))+1 != len(li): 
       thiselem = elem 
       nextelem = li[li.index(elem)+1] 
       print 'thiselem',thiselem 
       print 'nextel',nextelem 
      else: 
       print 'thiselem',li[li.index(elem)] 
       print 'nextel',li[li.index(elem)] 
संबंधित मुद्दे