2012-12-12 14 views
8

मान लीजिए कि मैं पाइथन में एक सूची से पहले तत्व, तीसरे से 200 वें तत्व, और अंतिम तत्व के माध्यम से अंतिम तत्व के माध्यम से 201 वें तत्व चाहता हूं।पायथन: अंतराल के साथ स्लाइस के लिए छोटा वाक्यविन्यास?

एक तरह से यह अलग अनुक्रमण और संयोजन के साथ है करने के लिए:

new_list = old_list[0:1] + old_list[3:201] + old_list[201::3] 

वहाँ old_list पर सिर्फ एक सूचकांक के साथ यह करने के लिए कोई तरीका है? मैं निम्नलिखित की तरह कुछ चाहते हैं (मैं यह नहीं करता है पता वाक्य रचना काम के बाद से सूची सूचकांक सूचियों नहीं किया जा सकता और अजगर के बाद दुर्भाग्य से doesn't have slice literals, मैं बस पास कुछ के लिए देख रहा हूँ):

new_list = old_list[[0, 3:201, 201::3]] 

मैं से कुछ हासिल कर सकते हैं यह NumPy arrays पर स्विच करके, लेकिन मुझे देशी पायथन सूचियों के लिए इसे कैसे करना है, इस बारे में अधिक रुचि है। मैं a slice maker या ऐसा कुछ भी बना सकता हूं, और संभवतः मजबूत हाथ जो मुझे मेरे सभी वांछित स्लाइसों की संरचना का प्रतिनिधित्व करने के लिए समकक्ष स्लाइस ऑब्जेक्ट देने में सक्षम था।

लेकिन मैं ऐसा कुछ ढूंढ रहा हूं जिसमें स्लाइस को प्रबंधित करने के लिए एक नई कक्षा बनाने में शामिल न हो। मैं बस स्लाइस सिंटैक्स को संयोजित करना चाहता हूं और अपनी सूची में फ़ीड करना चाहता हूं और सूची को समझना है कि इसका मतलब स्लाइस को अलग से प्राप्त करना और अंत में अपने संबंधित परिणामों को जोड़ना है।

+1

"पाइथन दुर्भाग्य से टुकड़ा प्राइमेटिव नहीं है" यहां तक ​​कि 'टुकड़ा' भी नहीं है? –

+0

क्षमा करें, मुझे टुकड़ा अक्षर कहा जाना चाहिए, टुकड़ा primitives नहीं। यही है, आप सिंटैक्स '(0: 10: 2)' के आसपास बस नहीं जा सकते हैं, जैसे कि वह स्वयं कुछ वस्तु थी जो हमेशा सूचकांक का प्रतिनिधित्व करती थी। आपको अपनी खुद की स्लाइस ऑब्जेक्ट बनाने की कठिन अतिरिक्त परत से गुजरना है, जो स्लाइस सिंटैक्स की सभी नस्लों को नष्ट कर देता है। मेरा [प्रश्न जो उपरोक्त में भी जुड़ा हुआ है] देखें (http://stackoverflow.com/questions/13706258/passing-python-slice-syntax-around-to- समारोह)। – ely

उत्तर

5

एक टुकड़ा निर्माता वस्तु (SliceMaker जैसे उद्देश्य के लिए एक कस्टम टुकड़ा बनाने के अपने अन्य प्रश्न, या np.s_) एकाधिक अल्पविराम से अलग स्लाइस स्वीकार कर सकते हैं; वे की एक tupleslice रों या अन्य वस्तुओं के रूप में प्राप्त कर रहे हैं:

from numpy import s_ 
s_[0, 3:5, 6::3] 
Out[1]: (0, slice(3, 5, None), slice(6, None, 3)) 

NumPy बहुआयामी सरणियों के लिए इस का उपयोग करता है, लेकिन आप टुकड़ा संयोजन के लिए उपयोग कर सकते हैं:

def xslice(arr, slices): 
    if isinstance(slices, tuple): 
     return sum((arr[s] if isinstance(s, slice) else [arr[s]] for s in slices), []) 
    elif isinstance(slices, slice): 
     return arr[slices] 
    else: 
     return [arr[slices]] 
xslice(list(range(10)), s_[0, 3:5, 6::3]) 
Out[1]: [0, 3, 4, 6, 9] 
xslice(list(range(10)), s_[1]) 
Out[2]: [1] 
xslice(list(range(10)), s_[:]) 
Out[3]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
+0

यह 'xslice (सूची (सीमा (10)), [1,2,3]) के लिए काम नहीं करता है, और न ही मेरा नवीनतम संशोधन करता है। मेरा पहला संशोधन करता है। – Dzhuang

+0

@Dzhuang धन्यवाद! 'इंस्टेंसेंस (..., स्लाइस)' का परीक्षण करने के लिए आपके संपादन में सुधार हुआ, बाद के 2 मामलों को स्वैप कर रहा था। – ecatmur

0

आप शायद अपने स्वयं के अनुक्रम प्रकार लिखने से बेहतर हैं।

>>> L = range(20) 
>>> L 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] 
>>> operator.itemgetter(*(range(1, 5) + range(10, 18, 3)))(L) 
(1, 2, 3, 4, 10, 13, 16) 

और प्राप्त करने के लिए आपको लगता है कि शुरू कर दिया:

>>> operator.itemgetter(*(range(*slice(1, 5).indices(len(L))) + range(*slice(10, 18, 3).indices(len(L)))))(L) 
(1, 2, 3, 4, 10, 13, 16) 
+0

मैं इन्हें बनाने के लिए 'itertools.islice' और' itertools.chain' का उपयोग करूंगा। – PaulMcG

0

क्यों नहीं सका आप से

>>> from itertools import chain, islice 
>>> it = range(50) 
>>> def cslice(iterable, *selectors): 
    return chain(*(islice(iterable,*s) for s in selectors)) 

>>> list(cslice(it,(1,5),(10,15),(25,None,3))) 
[1, 2, 3, 4, 10, 11, 12, 13, 14, 25, 28, 31, 34, 37, 40, 43, 46, 49] 
+1

क्या आपने ऊपर दिए गए लिंक को पिछले प्रश्न में देखा था जिसे मैंने पूछा है?उस प्रश्न का उत्तर आपके उत्तर के समान ही कम है, लेकिन बेहतर वाक्यविन्यास है और इसे 'itertools' की आवश्यकता नहीं है। मेरा मुख्य लक्ष्य सीधे स्लाइस सिंटैक्स के रूप में सीधे पास करना है। स्लाइस को टुपल्स के रूप में प्रस्तुत करने के सिंटैक्टिक ओवरहेड को जोड़ने और उन्हें एक नई वस्तु में पास करने से अलग स्लाइस को संयोजित करने से भी बदतर है। – ely

+0

@EMS: नहीं, वह उत्तर आसानी से स्लाइस बनाने के तरीके का वर्णन करता है, लेकिन इन्हें किसी सूची में तत्वों को अनुक्रमणित करने के लिए उपयोग नहीं किया जा सकता है। अभिजीत समाधान जो आप चाहते हैं वह करता है, और आप इसे एक अच्छा वाक्यविन्यास रखने के लिए दूसरे उत्तर के साथ जोड़ सकते हैं: 'cslice (it, make_slice [1: 5], make_slice [10:15], make_slice [25 :: 3]) ' – Bakuriu

+0

@ बाकुरी: यह मेरा पूरा बिंदु था। 'cslice' कुछ भी नहीं करता है लेकिन स्लाइस को चेन करता है, जो सूक्ष्म सूचियों से कम है। जवाब में, 'tsle's' cslice' के तर्क के रूप में उपयोग किया जाता है। मुझे यह दिखाने के लिए धन्यवाद कि 'स्लाइसमेकर' उदाहरण के परिणाम भी पारित किए जा सकते हैं। इससे इस उत्तर के कुछ सिंटैक्स ब्लोट को कम किया जा सकता है, लेकिन पर्याप्त नहीं है। – ely

0

सुनिश्चित नहीं हैं कि अगर यह "बेहतर है ", लेकिन यह इतना क्यों नहीं काम करता है ...

[y for x in [old_list[slice(*a)] for a in ((0,1),(3,201),(201,None,3))] for y in x]

यह शायद धीमी है (विशेष रूप से चा की तुलना में) लेकिन यह मूल पायथन (3.5.2 परीक्षण के लिए उपयोग किया जाता है)