2012-10-15 11 views
8

Chcę zastąpić podlistę z listy a, z inną pod-listą. Coś takiego:Wymiana podlisty na inną podlistę w pythonie

a=[1,3,5,10,13] 

Powiedzmy chcę wziąć podmenu jak:

a_sub=[3,5,10] 

i zastąpić go

b_sub=[9,7] 

więc wynik końcowy będzie

print(a) 
>>> [1,9,7,13] 

Wszelkie sugestie?

+0

I miałaś próbował niczego, bo nie mam pomysł, jak to zrobić. Szukałem pomysłów na stackoverflow przez około 2 godziny. – darxyde

+2

Czy znasz pozycję 'a_sub' w' a'? Czy 'a_sub' będzie zawsze w' a'? – sloth

+1

Nie znam pozycji 'a_sub' w' a', a 'a_sub' zawsze będzie w' a'. – darxyde

Odpowiedz

9
In [39]: a=[1,3,5,10,13] 

In [40]: sub_list_start = 1 

In [41]: sub_list_end = 3 

In [42]: a[sub_list_start : sub_list_end+1] = [9,7] 

In [43]: a 
Out[43]: [1, 9, 7, 13] 

nadzieję, że pomoże

+0

@AshwiniChaudhary w elementach case są unikalne * i * sub_list istnieje w. Jeśli sub_list nie jest w ... –

1

Musisz wziąć plaster od start_index do end_index + 1 i przypisać do niego swoją podlistę.

Tak jak można zrobić: - a[0] = 5 można podobnie przypisać podmenu do listy slice: - a[0:5] -> Tworzy plasterek z index 0 to index 4

Wszystko czego potrzebujesz to, aby dowiedzieć się position z następujących sublist chcesz zastąpić.

>>> a=[1,3,5,10,13] 

>>> b_sub = [9, 7] 

>>> a[1:4] = [9,7] # Substitute `slice` from 1 to 3 with the given list 

>>> a 
[1, 9, 7, 13] 
>>> 

Jak widać, że substituted podlistę nie muszą być tej samej długości substituting podmenu.

W rzeczywistości można zastąpić listę 4 długości z 2 listą długości i na odwrót.

+0

Interesującą częścią pytania jest znalezienie podlisty dowolnej długości na dowolnych listach długości. Bez zgniatania stosu. –

11

Można to zrobić ładnie z listy krojenia:

>>> a=[1, 3, 5, 10, 13] 
>>> a[1:4] = [9, 7] 
>>> a 
[1, 9, 7, 13] 

Jak więc dostać indeksy tutaj? Cóż, zacznijmy od znalezienia pierwszego. Skanujemy przedmiot po pozycji, dopóki nie znajdziemy pasującej podlisty i zwrócimy początek i koniec tej podlisty.

def find_first_sublist(seq, sublist, start=0): 
    length = len(sublist) 
    for index in range(start, len(seq)): 
     if seq[index:index+length] == sublist: 
      return index, index+length 

Możemy teraz wykonać naszą wymianę - zaczynamy na początku, należy wymienić pierwszy możemy znaleźć, a następnie spróbuj znaleźć inny po naszym nowo wykończone wymiany. Powtarzamy to, dopóki nie znajdziemy podlist, które można zastąpić.

def replace_sublist(seq, sublist, replacement): 
    length = len(replacement) 
    index = 0 
    for start, end in iter(lambda: find_first_sublist(seq, sublist, index), None): 
     seq[start:end] = replacement 
     index = start + length 

których możemy użyć ładnie:

>>> a=[1, 3, 5, 10, 13] 
>>> replace_sublist(a, [3, 5, 10], [9, 7]) 
>>> a 
[1, 9, 7, 13] 
+0

Dziękuję. Dokładnie to, czego potrzebowałem. – darxyde

+0

Myślę, że twoja funkcja 'find_sublist' może zostać uproszczona do' next (((i, i + length) dla i, x w wyliczeniu (seq) jeśli seq [i: i + length] == sublist), None) '. Ale w zależności od użycia, być może będziemy musieli trochę zmienić sposób, w jaki działa proces wymiany (powiedzmy, że chcesz wielokrotnie wymieniać coś na coś, co się zawiera). – DSM

+0

[Powoduje to nieprawidłowe wyniki ze względu na ponowne skanowanie zastąpionych sekcji listy. ] (https://ideone.com/fy3L8K) – user2357112

0

Tu jest inny sposób to zrobić.Ta metoda działa, jeśli musimy zastępuje więcej niż jednym podmenu:

a=[1,3,5,10,13] 
a_sub=[3,5,10] 
b_sub=[9,7] 

def replace_sub(a, a_sub, b_sub): 
    a_str = ',' + ','.join(map(str, a)) + ',' 
    a_sub_str = ',' + ','.join(map(str, a_sub)) + ',' 
    b_sub_str = ',' + ','.join(map(str, b_sub)) +',' 

    replaced_str = a_str.replace(a_sub_str, b_sub_str)[1 : -1] 

    return map(int, replaced_str.split(',')) 

Wynik:

>>> replace_sub(a, a_sub, b_sub) 
[1, 9, 7, 13] 
>>> replace_sub([10, 13, 4], [3, 4], [7]) 
[10, 13, 4] #[3,4] is not in the list so nothing happens 

wymienić więcej niż jeden podlistę:

>>> a=[1,3,5,10,13,3,5,10] 
>>> a_sub=[3,5,10] 
>>> b_sub=[9,7] 
>>> replace_sub(a, a_sub, b_sub) 
[1, 9, 7, 13, 9, 7] 
+0

Ostrożnie: 'replace_sub ([10, 13, 4], [3, 4], [7])' daje '[10, 17]' .. – DSM

+0

@ DSM Zwróciłem się do błędu, który wskazałeś, mam nadzieję, że są nie ma innych. – Akavall

Powiązane problemy