2011-10-27 16 views
5

Potrzebuję wskazówek lub przykładu, jak mogę zlokalizować na liście a listę b, a następnie zastąpić ją listą c.Python list issue

a=[1,3,6,2,6,7,3,4,5,6,6,7,8] 

wejście lista b (to podlistę program wyszukuje w liście a).

b=[6,7] 

gdy stwierdzono powrócić mnie indeksy były podlistę został znaleziony i zastąpić go za każdym razem z c=[0,0], więc wynik będzie

[1,3,6,2,0,0,3,4,5,6,0,0,8] 

Odpowiedz

1

dam wam przykład

li=[1,3,6,2,6,7,3,4,5,6,6,7,8] 
for i in range(len(li)): 
    if li[i:i + 2] == [3, 4]: 
     li[i:i + 2] = [0, 0] 

Myślę, że ten kod powinien zadziałać. Jeśli chcesz mieć bardziej odporny skrypt, sugeruję, aby sprawdzić wystąpienia podciągu na oryginalnej liście, edytować kopię (aby uniknąć niepożądanych zachowań).

+1

Kilka ulepszeń: używając nazw zmiennych używanych przez operację, możesz ustawić zakres jak 'range (len (a) - len (b))'; jeśli 'if a [i: i + len (b)] == b'; zadanie "a [i: i + len (b)] = c'. – jro

3

można zrobić coś podobnego do (napisany w Pythonie 3.2, użyj xrange w Pythonie 2.x):

for i in range(0, len(a)): 
    if a[i:i+len(b)] == b: 
     a[i:i+len(b)] = c 

ten będzie stanowił dla wykazów wszystkich rozmiarach. To zakłada list b == list c Nie wiem, czy to jest to, co chcesz, proszę podać, jeśli tak nie jest.

Wyjście na listach:

a = [1,2,3,4,5,6,7,8,9,0] 
b = [1,2] 
c = [0,0] 
Output: 
[0, 0, 3, 4, 5, 6, 7, 8, 9, 0] 
+0

oh wow, nawet nie widziałem listy b, będę edytować odpowiedź. EDYCJA: i zrobione – Serdalis

+0

Dla podanych wartości 'a, b, c' podanych w pytaniu, teraz zwraca' a' jako '[1, 3, 0, 0, 0, 0, 3, 4, 5, 6 , 0, 0, 8] ' – Johnsyweb

+1

Dzięki za naprawienie błędu wyrównania, który spowodowałem, pętla for testowała tylko pierwszą wartość, a teraz otrzymuję rozwiązanie, które wysłałeś = d – Serdalis

4

Oto bardziej efektywne podejście niż mój pierwszy przy użyciu list-krojenia:

>>> for i in xrange(len(a) - len(b) + 1): 
...  if a[i:i+len(b)] == b: 
...   a[i:i+len(b)] = c 
... 
>>> a 
[1, 3, 6, 2, 0, 0, 3, 4, 5, 6, 0, 0, 8] 

Pierwsza próba, dla potomnych ....

Jeśli nie potrzebujesz indeksów pośrednich, oto jedno podejście, używając funkcji łańcuchów i wykonując czynnościowe zatwierdzenie ch, nie modyfikując listy w miejscu.

>>> a_as_str = ','.join(str(i) for i in a) 
>>> print a_as_str 
1,3,6,2,6,7,3,4,5,6,6,7,8 
>>> b_as_str = ','.join(str(i) for i in b) 
>>> b_as_str 
'6,7' 
>>> c_as_str = ','.join(str(i) for i in c) 
>>> c_as_str 
'0,0' 
>>> replaced = a_as_str.replace(b_as_str, c_as_str) 
>>> replaced 
'1,3,6,2,0,0,3,4,5,6,0,0,8' 
>>> [int(i) for i in replaced.split(',')] 
[1, 3, 6, 2, 0, 0, 3, 4, 5, 6, 0, 0, 8] 

To może być refactored jak:

>>> def as_str(l): 
...  return ','.join(str(i) for i in l) 
... 
>>> def as_list_of_ints(s): 
...  return [int(i) for i in s.split(',')] 
... 
>>> as_list_of_ints(as_str(a).replace(as_str(b), as_str(c))) 
[1, 3, 6, 2, 0, 0, 3, 4, 5, 6, 0, 0, 8] 
+0

@Dvvoter, dlaczego? – Johnsyweb

+2

Konwersja z liczb całkowitych na ciągi iz powrotem jest dla mnie znacznie mniej czytelna niż bezpośrednie przeszukiwanie listy. Również ma to znaczącą karę wykonania (choć może to nie być istotne w tym przypadku). – amicitas

+0

@amicitas: Masz rację ... Zobacz edycję. – Johnsyweb

0

Ważne jest również, aby rozważyć, co się dzieje, gdy dany wzór jest tworzony przez podstawienie.

Myślę, że ta funkcja powinna traktować wszystkie przypadki zgodnie z przeznaczeniem:

def replace(a, b, c): 
    ii = 0 
    while ii <= (len(a) - len(b) + 1): 
     print(ii) 
     if a[ii:ii+len(b)] == b: 
      a[ii:ii+len(b)] = c 
      ii += len(b) 
     else: 
      ii += 1 
    return a 


Wyjście użyciu oryginalnego przykład:

[1, 3, 6, 2, 0, 0, 3, 4, 5, 6, 0, 0, 8] 


Oto przykład, gdzie podstawienie tworzy wyszukiwanie wzór:

a = [1,1,1,1,1,1,1,1,1,6,6,7,7,1] 
b = [6,7] 
c = [0,6] 

wyjściowe jest zgodnie z oczekiwaniami:

[1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 0, 6, 7, 1] 



Wszelkie pomysły jak to zrobić nieco bardziej zwięźle?