2016-03-15 9 views
5

Próbuję porównać dwie listy i znaleźć pozycję i zmienioną postać w tej pozycji. Na przykład są to dwie listy:Porównywanie dwóch list i znajdowanie indeksów zmian

list1 = ['I', 'C', 'A', 'N', 'R', 'U', 'N'] 
list2 = ['I', 'K', 'A', 'N', 'R', 'U', 'T'] 

Chcę mieć możliwość wyprowadzania pozycji i zmiany różnic między tymi listami. Jak widać, literę można powtórzyć wiele razy w innej pozycji indeksu. To jest kod, który próbowałem, ale nie mogę wydrukować dokładnie drugiej lokalizacji.

for indexing in range(0, len(list1)): 
    if list1[indexing] != list2[indexing]: 
     dontuseindex = indexing 
     poschange = indexing + 1 
     changecharacter = list2[indexing] 
for indexingagain in range(dontuseindex + 1, len(list1)): 
    if list1[indexingagain] != list2[indexingagain]: 
     secondposchange = indexingagain + 1 
     secondchangecharacter = list2[indexingagain] 

Czy istnieje lepszy sposób rozwiązania tego problemu lub sugestii dotyczących kodu, który mam?

Moje oczekiwany wynik byłby:

2 K 
7 T 
+0

Czy chodzi ci tylko o zamienniki, czy też o insercje/skreślenia? W pierwszym przypadku: Po prostu 'zip' i porównaj; w tym drugim przypadku użyj wariantu [Levenshtein distance] (https: //en.wikipedia.org/wiki/Levenshtein_distance) –

+0

@PeterWood podał moje oczekiwane wyjście – interstellar

+0

@tobias_k Mam na myśli tylko zamienniki. Listy będą zawsze miały tę samą długość. – interstellar

Odpowiedz

7
for index, (first, second) in enumerate(zip(list1, list2)): 
    if first != second: 
     print(index, second) 

wyjściowa:

1 K 
6 T 

Jeśli chcesz wyjście dałeś, musimy się liczyć z 1 zamiast zwykłej 0:

for index, (first, second) in enumerate(zip(list1, list2), start=1): 
+0

Myślę, że to powinno działać dobrze i powinienem być w stanie go łatwo wdrożyć. Dziękuję Ci! – interstellar

+0

Czy istnieje prosty sposób na zapisanie zmian i indeksów w dwóch oddzielnych zmiennych? Na przykład 'position1',' position2', 'change1',' change2'? – interstellar

+0

Co zrobić, jeśli są 3 zmiany? Może powinieneś pomyśleć o tym nieco i zadać to jako osobne pytanie, po przeszukaniu. –

4

Inną możliwością, aby zapisać wszystkie nie-równe elementy z indeksu jest z listowych:

list1 = ['I', 'C', 'A', 'N', 'R', 'U', 'N'] 
list2 = ['I', 'K', 'A', 'N', 'R', 'U', 'T'] 

# Append index, element1 and element2 as tuple to the list if they are not equal 
changes = [(i, list1[i], list2[i]) for i in range(len(list1)) if list1[i] != list2[i]] 
print(changes) 
#prints [(1, 'C', 'K'), (6, 'N', 'T')] 

Nie dokładnie to, co określono jako wyjście, ale jest blisko.

Można wydrukować określoną wyjście z pętli:

for i in changes: 
    print(i[0] + 1, i[1]) 
# 2 K 
# 7 T 

w komentarzach kilka alternatywnych sposobów projektowania listowych zostały zaproponowane:

  • Korzystanie enumerate i zip:

    changes = [(i, e1, e2) for i, (e1, e2) in enumerate(zip(list1, list2)) if e1 != e2] 
    
  • Usi ng enumerate z indeksu początkowego i zip:

    changes = [(i, e1, e2) for i, (e1, e2) in enumerate(zip(list1, list2), 1) if e1 != e2] 
    
  • Stosując zip i itertools.count:

    import itertools 
    changes = [(i, e1, e2) for i, e1, e2 in zip(itertools.count(), list1, list2)) if e1 != e2] 
    
  • Stosując zip i itertools.count z uruchomieniem wskaźnika:

    changes = [(i, e1, e2) for i, e1, e2 in zip(itertools.count(1), list1, list2)) if e1 != e2] 
    

Wszystkie z nich dają taki sam wynik, jak oryginał, ale używają innych (lepszych) funkcji python.

+2

Dlaczego nie 'zip' i' wyliczyć'? –

+0

To działało świetnie! :) :) – interstellar

+0

To nie jest bardzo pyton. –