2010-04-13 19 views
36

मुझे लगता है कि मैं पाइथन में कोड लिखने में काफी समय बिताता हूं, लेकिन पाइथनिक कोड बनाने में पर्याप्त समय नहीं लगता। हाल ही में मैं एक मजेदार छोटी समस्या में भाग गया जो मैंने सोचा कि एक आसान, मूर्खतापूर्ण समाधान हो सकता है। मूल को पारदर्शी, मुझे सूची में प्रत्येक अनुक्रमिक जोड़ी एकत्र करने की आवश्यकता थी। उदाहरण के लिए, सूची [1,2,3,4,5,6] दी गई, मैं [(1,2),(3,4),(5,6)] की गणना करना चाहता था।पायथन "हर अन्य तत्व" Idiom

मैं उस समय एक त्वरित समाधान के साथ आया था जब अनुवादित जावा की तरह दिखता था। प्रश्न की समीक्षा, सबसे अच्छा मैं कर सकता

l = [1,2,3,4,5,6] 
[(l[2*x],l[2*x+1]) for x in range(len(l)/2)] 

जो मामले में पिछले संख्या बाहर घालना के दुष्प्रभाव यह है कि लंबाई भी नहीं दे रहा है था।

क्या कोई और मूर्खतापूर्ण दृष्टिकोण है जिसे मैं याद कर रहा हूं, या यह सबसे अच्छा है जिसे मैं प्राप्त करने जा रहा हूं?

+0

संबंधित pythonic "क्या सबसे अधिक है" (अजीब लंबाई की सूची के लिए अंतिम प्रविष्टि पैड के लिए एक विकल्प के साथ) इस को हल करती है "जिस तरह से मात्रा में एक सूची से अधिक पुनरावृति करने के लिए?" http://stackoverflow.com/questions/434287/what-is-the-most-pythonic-way-to-iterate-over-a-list-in-chunks – jfs

उत्तर

78

यह थोड़ा और बड़े करीने से यह करना होगा:

>>> data = [1,2,3,4,5,6] 
>>> zip(data[0::2], data[1::2]) 
[(1, 2), (3, 4), (5, 6)] 

(लेकिन यह यकीनन कम पठनीय है कि अगर आप पर्वतमाला की "कदम" सुविधा से परिचित नहीं हैं)।

अपने कोड की तरह, यह अंतिम मान को छोड़ देता है जहां आपके पास मूल्यों की एक विषम संख्या है।

+3

'ज़िप' फ़ंक्शन से प्यार करें। –

+2

आइटम परिदृश्य की विषम संख्या को संभालने के लिए उपर्युक्त करने से पहले आप 'डेटा + = [कोई नहीं]' कर सकते हैं। – badp

+1

'some_list + = [foo] 'लिखा है' some_list.append (foo)'। –

8

कैसे range() के कदम सुविधा का उपयोग कर के बारे में:

[(l[n],l[n+1]) for n in range(0,len(l),2)] 
48

अक्सर उद्धृत एक है:

zip(*[iter(l)] * 2) 
+8

अजीब, लेकिन perl की तरह पढ़ता है; -) –

+0

सच है, लेकिन यह अब तक का सबसे कुशल समाधान भी प्रस्तुत किया गया है, मुझे लगता है। मैं परीक्षण करूंगा, बीआरबी। – jemfinch

+1

हां, यह रिचइंडल के समाधान से लगभग 10% की तुलना में तेज़ है, क्योंकि इसमें स्मृति की आवंटन की आवश्यकता नहीं है और इनपुट सूची में केवल एक ही पुनरावृत्ति की आवश्यकता नहीं है। – jemfinch

4

कोशिश इस

def pairs(l, n): 
    return zip(*[l[i::n] for i in range(n)]) 

तो,

pairs([1, 2, 3, 4], 2) देता

[(1, 2), (3, 4)] 
9

मैं आमतौर पर इस के लिए मेरे कोड में itertools प्रलेखन से grouper नुस्खा नकल।

def grouper(n, iterable, fillvalue=None): 
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" 
    args = [iter(iterable)] * n 
    return izip_longest(fillvalue=fillvalue, *args) 
+1

+1 :) – tzot

3

आप अगर सूची में उनकी संख्या भी कोशिश नहीं कर रहा है तत्व कम करने के लिए नहीं करना चाहते हैं इस:

>>> l = [1, 2, 3, 4, 5] 
>>> [(l[i], l[i+1] if i+1 < len(l) else None) for i in range(0, len(l), 2)] 
[(1, 2), (3, 4), (5, None)] 
4

सही बात शायद सूचियों गणना करने के लिए नहीं है, लेकिन एक iterator- लिखना है > इटरेटर समारोह। यह अधिक सामान्य है - यह हर पुनरावर्तनीय पर काम करता है, और यदि आप इसे एक सूची में "फ्रीज" करना चाहते हैं, तो आप "सूची()" फ़ंक्शन का उपयोग कर सकते हैं। शायद एक भविष्य संशोधन -

def groupElements(iterable, n): 
    # For your case, you can hardcode n=2, but I wanted the general case here. 
    # Also, you do not specify what to do if the 
    # length of the list is not divisible by 2 
    # I chose here to drop such elements 
    source = iter(iterable) 
    while True: 
     l = [] 
     for i in range(n): 
      l.append(source.next()) 
     yield tuple(l) 

मैं हैरान itertools मॉड्यूल पहले से ही उस के लिए एक समारोह नहीं है हूँ। तब तक, ऊपर दिए गए संस्करण का उपयोग करने के लिए स्वतंत्र महसूस करें :)

+0

प्रदर्शन के अनुसार यह क्या है? – LondonRob

4

toolz एक अच्छी तरह से निर्मित लाइब्रेरी है जिसमें कई कार्यात्मक प्रोग्रामिंग नस्लों के साथ इटारटोल में अनदेखा किया गया है।partition

>>> list(toolz.partition(2, [1,2,3,4,5,6])) 
[(1, 2), (3, 4), (5, 6)] 
संबंधित मुद्दे