2011-08-10 13 views
12

अजगर में, यह कश्मीर आकार के टुकड़ों में एक n लंबी सूची को तोड़ने के लिए आसान है, तो nकश्मीर (IOW, n % k == 0) की एक बहु है। यहाँ मेरा पसंदीदा दृष्टिकोण (docs से सीधे) है:।एन-के-लम्बे भाग में एन-लांग सूची तोड़ने के लिए सरल मुहावरे, जब एन% के> 0?

>>> k = 3 
>>> n = 5 * k 
>>> x = range(k * 5) 
>>> zip(*[iter(x)] * k) 
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 14)] 

(चाल कि [iter(x)] * kकश्मीर संदर्भ की एक सूची के लिए एक ही इटरेटर, के रूप में iter(x) द्वारा लौटाए का उत्पादन होता है तब zip द्वारा प्रत्येक हिस्सा उत्पन्न करता है इटरेटर की कश्मीर प्रतियों की प्रत्येक ठीक एक बार बुला। *[iter(x)] * k से पहले आवश्यक है क्योंकि zip के रूप में "अलग" iterators, बजाय उन्हें की एक सूची अपने तर्कों प्राप्त करने की उम्मीद है।)

+०१२३५१६४१०६१

मुख्य कमी मैं इस मुहावरे के साथ देख सकते हैं कि, nकश्मीर (IOW, n % k > 0), प्रविष्टियों बचे सिर्फ बाहर छोड़ दिया जाता की एक बहु नहीं है जब है, उदाहरण के लिए:

>>> zip(*[iter(x)] * (k + 1)) 
[(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11)] 

वहाँ एक विकल्प मुहावरा थोड़ा लंबा टाइप करने के लिए है कि, एक के ऊपर जब n % k == 0 रूप में एक ही परिणाम पैदा करता है, और एक अधिक स्वीकार्य व्यवहार जब n % k > 0 है है: कम से कम

>>> map(None, *[iter(x)] * k) 
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 14)] 
>>> map(None, *[iter(x)] * (k + 1)) 
[(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11), (12, 13, 14, None)] 

, यहां बाईं ओर प्रविष्टियां बरकरार रखी गई हैं, लेकिन अंतिम खंड None के साथ गद्देदार हो जाता है। यदि कोई सिर्फ पैडिंग के लिए एक अलग मूल्य चाहता है, तो itertools.izip_longest समस्या हल करता है।

लेकिन लगता वांछित समाधान है जिसमें पिछले हिस्सा unpadded छोड़ दिया जाता है, अर्थात

[(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11), (12, 13, 14)] 

वहाँ एक सरल रास्ता map(None, *[iter(x)]*k) मुहावरा इस परिणाम का उत्पादन करने के संशोधित करने के लिए है?

(माना जाता है कि एक फ़ंक्शन लिखकर इस समस्या को हल करना मुश्किल नहीं है (उदाहरण के लिए, How do you split a list into evenly sized chunks? या What is the most "pythonic" way to iterate over a list in chunks? पर कई अच्छे उत्तरों को देखें)। इसलिए, इस प्रश्न के लिए एक और सटीक शीर्षक "कैसे बचाया जाएगा" map(None, *[iter(x)]*k) मुहावरा? ", लेकिन मुझे लगता है कि पाठकों का एक बहुत भ्रमित होगा।)

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

+0

क्या आप इसे एक व्यावहारिक कारण पूछ रहे हैं, या सिर्फ यह देखने के लिए कि क्या यह किया जा सकता है? –

+0

क्या यह http://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks-in-python का डुप्लिकेट नहीं है? –

+0

@Ned Batchelder: मैंने यह स्पष्ट करने की कोशिश की कि यह पोस्ट एक अनुवर्ती/विस्तार था (वास्तव में, मैं अंत में एक ही स्टैक ओवरफ्लो पोस्ट उद्धृत करता हूं)। साथ ही, जैसा कि मैंने इस पोस्ट के अंत में व्याख्या करने की कोशिश की है, यह पोस्ट चंकिंग समस्या को हल करने के बारे में कम है (इसके लिए अच्छे समाधान दिए गए पदों में दिए गए हैं), लेकिन यह पता लगाने के लिए कि क्या विस्तार करने का एक आसान तरीका है एक विशेष पायथन मुहावरे की उपयोगिता। हो सकता है कि पदों को एक अलग शीर्षक की आवश्यकता हो, लेकिन जिन सभी को मैं सोच सकता था भ्रमित लग रहा था ... – kjo

उत्तर

3
sentinal = object() 
split = ( 
    (v for v in r if v is not sentinal) for r in 
    izip_longest(*[iter(x)]*n, fillvalue=sentinal)) 
बेशक

, बेहतर मुहावरा के रूप में है कि अधिक पठनीय तो कुछ भी है कि एक ही बात करूँगा हो जाएगा एक समारोह कॉल करने के लिए है।

1

इसके बारे में क्या?यह एक अलग मुहावरा है, लेकिन अपने वांछित परिणाम पैदा करता है:

[x[i:i+k] for i in range(0,len(x),k)] #=> [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14]] 
[x[i:i+k] for i in range(0,len(x),k)] #=> [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14]] 

या यदि आप वास्तव में tuples की जरूरत है, बस x[i:i+k] के बजाय tuple(x[i:i+k]) का उपयोग करें।

3
IPython के स्रोत से

:

def chop(seq,size): 
    """Chop a sequence into chunks of the given size.""" 
    chunk = lambda i: seq[i:i+size] 
    return map(chunk,xrange(0,len(seq),size)) 

पिछले सूची लौटे तुलना में कम chunk तत्वों होगा यदि अनुक्रम में समान रूप से विभाज्य नहीं है, मूल रूप से यह छड़ी की लेकिन शिकायत के बिना कम अंत हो जाता है।

>>> chop(range(12),3) 
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]] 
>>> chop(range(12),4) 
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]] 
>>> chop(range(12),5) 
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11]] 
>>> chop(range(12),6) 
[[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]] 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^