2012-12-12 26 views
8

Python'daki bir listeden ilk öğe olan 3. ve 200. elemanlar ile 201st elemanının son öğe içinden 3. adımda olmasını istiyorum. old_list sadece bir indeksi ile bunu yapmanın bir yolu var mıPython: boşluklu dilimler için kısa sözdizimi?

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

:

bir yolu ayrı endeksleme ve birleştirme aracılığı ile olduğunu yapmalı?

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

Ben bazılarını elde edebilirsiniz: (Sadece yakın bir şey arıyorum liste endeksleri listeleri olamaz ve Python beri maalesef doesn't have slice literals beri bu değil biliyorum sözdizimsel işi) Ben aşağıdaki gibi bir şey istiyorum Bu, NumPy dizilerine geçerek, ancak yerel Python listeleri için nasıl yapılacağıyla ilgileniyorum. Ayrıca, a slice maker veya bunun gibi bir şey yaratabiliyordum ve muhtemelen benim istediğim tüm dilimlerin kompozisyonunu temsil etmek için eşdeğer bir dilim nesnesi vermek için güçlü bir kol oluşturabiliyordum.

Dilleri yönetmek için yeni bir sınıf oluşturmayı gerektirmeyen bir şey arıyorum. Ben sadece dilim sözdizimini bir araya getirmek ve bunu listeme beslemek ve listenin dilimlerini ayrı ayrı almanın ve sonuçların sonunda sonuçlarının birleştirilmesi gerektiğini anlamasını istiyorum.

+1

"Python maalesef dilim ilkellerine sahip değildir" Dilim bile değil mi? –

+0

Üzgünüm, dilim harfleri değil, dilim ilkellerini söylemeliydim. Yani, sözdiziminin (0: 10: 2) sözdizimini, her zaman indeksleri temsil eden bir nesne gibi geçemezsiniz. Dilim sözdiziminin tüm güzellerini yok eden kendi dilim nesnesini yapmak için can sıkıcı ekstra katmandan geçmek zorundasınız. Benim de [yukarıda da bağlantılı olan soruyu] gör (http://stackoverflow.com/questions/13706258/passing-python-slice-syntax-around-to-functions). – ely

cevap

5

bir dilim yapımcısı nesneyi (örneğin SliceMaker özel dilim oluşturmak t senin diğer soru, veya np.s_) birden çok virgülle ayrılmış dilimi kabul edebilir; onlar tupleslice s veya diğer nesnelerin olarak alınan:

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

NumPy çok boyutlu diziler için bu kullanır, ancak dilim Ulama için kullanabilirsiniz: Bu "daha iyiyse

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 (liste (aralık (10)), [1,2,3]) '' için çalışmaz, ya da en son revizyonum. İlk revizyonum var. – Dzhuang

+0

@Dzhuang teşekkürler! Son 2 vakayı değiştirerek, "insinstance (..., slice)" i test etmek için düzenlemenizi geliştirdiniz. – ecatmur

0

Kendi dizi türünüzü yazmanız daha iyi olabilir.

>>> 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) 

Ve almak için bu konuda başlatılan:

>>> 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

Bunlar oluşturmak için 'itertools.islice' ve' itertools.chain' kullanıyorum. – PaulMcG

0

Neden don, siz adresinin amaçla

>>> 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

Yukarıda eklediğim bağlantıya sorduğum bir önceki soruya baktınız mı?Bu sorunun cevabı az ya da çok cevabınızla aynı şeyi içeriyor, ama daha iyi bir sözdizimine sahip ve itertools'a ihtiyaç duymuyor. Benim ana hedefim, tam olarak dilimleme sözdizimini olduğu gibi geçirmektir. Dilimleri tupl olarak temsil eden ve yeni bir nesneye geçirmenin sözdizimsel ek yükünü eklemek, ayrı ayrı dilimleri birleştirmekten bile daha kötüdür. – ely

+0

@EMS: hayır, bu cevap sadece dilimleri kolayca oluşturmanın bir yolunu tanımlar, ancak listedeki öğeleri indekslemek için kullanılamazlar. Abhijit çözümü istediğiniz şeyi yapar ve hoş bir sözdizimine sahip olmak için diğer cevapla birleştirebilirsiniz: cslice (it, make_slice [1: 5], make_slice [10:15], make_slice [25 :: 3]) – Bakuriu

+0

@Bakuriu: Bu benim bütün amacımdı. 'cslice' hiçbir şey yapmaz, ancak zincirleme listelerini birleştirmekten daha düşük olan dilimleri zincirler. Cevapta, tuple 'cslice' için argümanlar olarak kullanılır. "SliceMaker" örneğinin sonuçlarının da iletilebileceğini gösterdiğiniz için teşekkür ederiz. Bu yanıtın bazı sözdizimi bloğunu hafifletir ancak bu yeterli değildir. – ely

0

emin değil " ama özellikle cha karşılaştırıldığında (muhtemelen yavaş

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

... neden olmasın çalışır in) ama temel python (test için kullanılan 3.5.2)