2015-12-05 22 views
5

Biorąc pod uwagę niektóre macierzy, muszę odzwierciedlić wszystkie wiersze w macierzy. Na przykładDublowanie wierszy w macierzy za pomocą pętli/rekursji?

[[2, 1], 
[4, 3]] 

staną

[[1, 2], 
[3, 4]] 

udało mi się zrobić to dla (2 x 2) -case. Ale mam kłopoty mirroring coś takiego:

[[1, 2, 3, 4], 
[1, 2, 3, 4]] 

To musi stać

[[4, 3, 2, 1], 
[4, 3, 2, 1]] 

Chcę to zrobić z pętli/rekursji. Gdybym użył rekursji, prawdopodobnie miałbym taki podstawowy krok, że większość elementów wewnętrznych zostanie zamieniona jako pierwsza, a następnie od tego momentu zwiększy się rozmiar macierzy, włączając również elementy zewnętrzne i zamieniamy je również. Mam jednak problem z krokiem rekursji. Po zamianie najbardziej wewnętrznych elementów, chciałbym umieścić obok siebie większość wewnętrznych elementów w macierzy, a także zamienić je, a następnie kontynuować tak, aż dotrzemy do zewnętrznych elementów. Jak można to zaimplementować w kodzie? Oto, co zrobiłem do tej pory:

matrix = [[1, 2, 3, 4], 
      [1, 2, 3, 4]] 

def mirror(matrix): 
    # This corresponds to the basic step. The two inner most elements get swapped. 
    if len(matrix) == 2: 
     for i in range(len(matrix)): 
      for j in range(len(matrix)): 
       # Store one element in a temporal variable 
       temp = matrix[i][j] 
       matrix[i][j] = matrix[i][len(matrix) - 1] 
       matrix[i][len(matrix)-1] = temp 
       return matrix 

    else: 
     # Recursion step 
     for i in range(len(matrix)): 
      for j in range(len(matrix)): 
       return (matrix + mirror(matrix[(len(matrix) // 2) - 1 : len(matrix)])) 

Krok rekursji jest źle Myślę. Próbowałem użyć operatora plastra, ale nie jestem pewien, jak to zrobić poprawnie. Każda pomoc z tym problemem byłaby doceniona.

+0

to ma być rekurencyjne? –

+0

Cóż, w Pythonie analizowałem tylko pętle, rekurencję, listy, algorytmy wyszukiwania i funkcje. Tak więc na podstawie mojej ograniczonej wiedzy myślę, że rekurencja jest najłatwiejszym/najskuteczniejszym sposobem rozwiązania tego problemu. – Kamil

+0

'[sub [:: - 1] dla sub w arr]' jest najprostszym rozwiązaniem, czy chcesz zmienić oryginalną tablicę? –

Odpowiedz

4

rekurencyjna rozwiązanie jest dość trywialne, po prostu recurse całej tablicy cofanie każdej podprzestrzeni:

arr= [[2, 1], 
[4, 3]] 

def reve(l): 
    # if we have recursed across all sub arrays just return empty list 
    if not l: 
     return [] 
    # else reverse the first current sublist l[0] and recurse on the remaining sublists 
    return [l[0][::-1]] + reve(l[1:]) 


print(reve(arr)) 
[[1, 2], [3, 4]] 

które mogą być napisane zwięźle jak:

def reve(l): 
    return [l[0][::-1]] + reve(l[1:]) if l else [] 

Jeśli chciałeś inplace:

arr = [[1, 2, 3, 4], 
    [1, 2, 3, 4]] 

def reve(l): 
    if not l: 
     return 
    # call inplace list.reverse on each sublist 
    l[0].reverse() 
    return reve(l[1:]) 


reve(arr) 

wyjściowa:

[[4, 3, 2, 1], [4, 3, 2, 1]] 

A la stly możemy osiągnąć to, co chcesz inplace bez krojenia w ogóle używając iter ze specjalnej metody __length__hint:

def reve(l): 
    if l.__length_hint__() == 0: 
     return 
    sub = next(l) 
    sub.reverse() 
    return reve(l) 


reve(iter(arr)) 

print(arr) 

wyjściowa:

[[4, 3, 2, 1], [4, 3, 2, 1]] 
+0

Mam problemy ze zrozumieniem twojego kodu. Co robi [l [0] [:: -1]] + reve (l [1:])? Czy jest to krok rekursji, który wygląda tylko na dwóch najbardziej wewnętrznych elementach i zamienia je? – Kamil

+0

@Kamil, 'l [0]' jest każdą podlistą, gdy przechodzimy przez listę przekazaną od pierwszego, 'reve (l [1:])' przesuwa się po liście, l [1:], l [2 :] ... aż l == [] –

1

W rzeczywistości, bardziej Pythonicznym sposobem na to byłoby używanie wyrażeń listowych. Możesz to zrobić po prostu przez:

matrix = [[1, 2, 3, 4], 
     [1, 2, 3, 4]] 
reversed_matrix = (i[::-1] for i in matrix) 

reverse_matrix będzie wyrażeniem generatora. Możesz przekształcić go na listę przez zamianę "()" na "[]" W zrozumieniu listy.

i[::-1] odwraca tablica w miejscu za pomocą operatora plasterek

2

Obie funkcje mogą korzystać z funkcji map, ale można użyć także imperatyw for. Jeśli chodzi o moje rekursywne podejście, instrukcja else odnosi się do wszystkich przypadków pomiędzy ostatecznym i drugim elementem listy, są one łączone aż do osiągnięcia pierwszego elementu.

Moja rekurencyjnej podejście:

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

def mirror(matrix): 
    def revert(row): 
     if len(row) == 1: 
      return [row[0]] 
     else: 
      return [row[-1]] + revert(row[:-1]) # concatenates two lists. 

    return [revert(row) for row in matrix] 

mirror(a) 

Moja deklaratywne podejście:

def mirror(matrix): 
    def revert(row): 
     return row[::-1] # copies the array in reverse order 

    return list(map(revert, matrix)) #<-for python3, and just map(...) for python2 

mirror(a) 

Oba wyjścia funkcje

[[3, 2, 1], [7, 6, 5]]

+0

Ten kod nie działa dla mnie. Mówi "obiekt mapy na 0x12343" lub coś podobnego. Nie rozumiem twojego "innego" kroku w rekursywnym podejściu, a także co robi mapa? Pamiętaj, że jestem tylko początkującym użytkownikiem Pythona. – Kamil

+0

@Kamil jakiej wersji python używasz? i dodałem dokumentację mapy, jednak najłatwiejszym sposobem myślenia o 'mapie' w pytonie jest" [A] => [B] ", gdzie długość obu list (A i B) jest taka sama, a strzałka reprezentuje modyfikację każdego elementu. Jednak zamiast tego możesz użyć a, wkrótce dodam alternatywę. –

+0

Czy osoba, która negatywnie głosowała, może podać mi przyczynę? –