2012-10-15 12 views
8

Ich möchte eine Unterliste von der Liste a durch eine andere Unterliste ersetzen. Etwas wie folgt aus:Eine Unterliste durch eine andere Unterliste in Python ersetzen

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

Lets sagen, dass ich eine Unterliste wie nehmen wollen:

a_sub=[3,5,10] 

und ersetzen sie durch

b_sub=[9,7] 

so dass das Endergebnis wird

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

Irgendwelche Vorschläge?

+0

ich habe alles versucht, weil ich nicht haben Idee, wie es geht. Ich habe auf Stackoverflow für ca. 2 Stunden nach Ideen gesucht. – darxyde

+2

Kennen Sie die Position von 'a_sub' in' a'? Wird 'a_sub' immer in' a' sein? – sloth

+1

Ich weiß nicht die Position von 'a_sub' in' a', und 'a_sub' wird immer in' a' sein. – darxyde

Antwort

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] 

Hoffnung, die

+0

@AshwiniChaudhary, falls Elemente eindeutig sind * und * sub_list existiert in a. Wenn sub_list nicht in einem ... –

1

Sie müssen ein Stück von start_index bis end_index + 1 nehmen und ihm Ihre Unterliste zuweisen.

Genau wie Sie tun können: - a[0] = 5, Sie in ähnlicher Weise eine Unterliste zu Ihrem zuweisen slice: - a[0:5] -> Erzeugt eine Scheibe von index 0 to index 4

Alles, was Sie brauchen, ist die position der um herauszufinden, sublist Sie wollen ersetzen.

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

Wie Sie das sehen können, substituted sublist müssen nicht sein von gleicher Länge des sublist substituting.

In der Tat können Sie ersetzen, 4 Längenliste mit 2 Längenliste und umgekehrt.

+0

Der interessante Teil der Frage ist, Sublisten beliebiger Länge in Listen beliebiger Länge zu finden. Ohne den Stapel zu sprengen. –

11

Sie hilft dies mit Liste schneiden gut tun:

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

Wie bekommen wir die hier Indizes? Nun, fangen wir damit an, den ersten zu finden. Wir scannen Artikel für Artikel, bis wir eine passende Unterliste finden, und geben den Anfang und das Ende dieser Unterliste zurück.

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 

Wir können nun unseren Ersatz tun - wir am Anfang beginnen, ersetzen Sie das erste, das wir finden, und dann versuchen, eine andere nach unserem neu fertig Ersatz zu finden. Wir wiederholen dies, bis wir keine Unterlisten mehr finden können.

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 

Was wir gut verwenden können:

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

Vielen Dank. Genau das, was ich brauchte. – darxyde

+0

Ich denke, Ihre 'find_sublist' -Funktion kann vereinfacht werden zu' next (((i, i + length) für i, x in enumerate (seq) wenn seq [i: i + length] == Unterliste), None) '. Aber abhängig vom Anwendungsfall müssen wir vielleicht ein wenig ausgefeilter sein, wie der Ersetzungsprozess funktioniert (sagen wir, dass Sie wiederholt etwas durch etwas ersetzen wollen, das sich selbst enthält). – DSM

+0

[Dies führt zu falschen Ergebnissen aufgrund von ersetzten Sektionen der Liste. ] (https://ideone.com/fy3L8K) – user2357112

0

Hier ist eine andere Art und Weise, dies zu tun.Diese Methode funktioniert, wenn wir mehr als eine Teilliste ersetzt müssen:

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(',')) 

Ergebnis:

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

Ersetzen Sie mehr als eine Unterliste:

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

Vorsicht: 'replace_sub ([10, 13, 4], [3, 4], [7])' gibt '[10, 17]' .. – DSM

+0

@DSM Ich habe den Fehler angesprochen, auf den Sie hingewiesen haben, hoffentlich gibt es keine Anderen. – Akavall

Verwandte Themen