2015-12-05 5 views
5

Dato un po 'di matrice, ho bisogno di specchiare tutte le righe nella matrice. Per esempioMirroring di righe in matrice con loop/ricorsione?

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

sarebbe diventato

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

sono riuscito a farlo per la (2 x 2) CAUSA. Ma Ho problemi di mirroring o meno così:

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

Questo deve diventare

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

io voglio fare questo con i loop/ricorsione. Se uso la ricorsione, probabilmente avrei come passo base che gli elementi più interni vengono scambiati per primi, e da qui in poi renderemmo la matrice più grande includendo anche gli elementi esterni e scambiandoli anche loro. Tuttavia, ho problemi con la fase di ricorsione. Dopo aver scambiato gli elementi più interni, voglio includere il prossimo alla maggior parte degli elementi interni della matrice, e scambiarli anch'essi, e poi continuare così fino a raggiungere gli elementi esterni. Come può essere implementato nel codice? Questo è quello che ho fatto finora:

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

Il passaggio di ricorsione è sbagliato, credo. Ho provato ad usare l'operatore di slice, ma non sono sicuro di come dovrebbe essere fatto correttamente. Qualsiasi aiuto con questo problema sarebbe apprezzato.

+0

ha a essere ricorsiva? –

+0

Beh, ho studiato solo loop, ricorsione, liste, algoritmi di ricerca e funzioni con Python. Pertanto, sulla base delle mie conoscenze limitate, ritengo che la ricorsione sia il modo più semplice/più efficace per affrontare questo problema. – Kamil

+0

'[sub [:: - 1] per sub in arr]' è la soluzione più semplice, vuoi cambiare l'array originale? –

risposta

4

Una soluzione ricorsiva è piuttosto banale, basta recurse attraverso l'array invertire ciascun sottotitolo:

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

che può essere scritto in modo conciso come:

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

Se si voleva 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) 

uscita:

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

e La stly siamo in grado di ottenere quello che vuoi inplace senza affettare a tutti utilizzando iter con il metodo speciale __length__hint:

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


reve(iter(arr)) 

print(arr) 

uscita:

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

Ho problemi a capire il tuo codice. Cosa fa [l [0] [:: -1]] + reve (l [1:])? È questo il passo di ricorsione che guarda solo ai due elementi più interni e lo scambia? – Kamil

+0

@Kamil, 'l [0]' è ogni sottolista mentre ricusiamo attraverso la lista passata a partire dal primo, 'reve (l [1:])' si muove attraverso la lista, l [1:], l [2 :] ... fino a l == [] –

1

In realtà, un modo più plateale di fare ciò sarebbe utilizzare le list comprehensions. Puoi farlo semplicemente:

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

reverseedmatrix sarà un'espressione di generatore. Puoi convertirlo in una lista sostituendo "()" con "[]" nella comprensione della lista.

i[::-1] inverte la matrice sul posto utilizzando fetta operatore

2

Entrambe le funzioni possono utilizzare la funzione di map, ma è possibile utilizzare un imperativo for anche. Per quanto riguarda il mio approccio ricorsivo, l'enunciato else si riferisce a tutti i casi tra l'ultimo e il secondo elemento dell'elenco, vengono concatenati fino al raggiungimento del primo elemento.

Il mio approccio ricorsivo:

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) 

Il mio approccio dichiarativo:

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) 

Entrambe le uscite funzioni

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

+0

Questo codice non funziona per me. Dice "map object at 0x12343" o qualcosa del genere. Non capisco il tuo 'altro' passo nell'approccio ricorsivo, e anche cosa fa la mappa? Tieni presente che sono solo un principiante con Python. – Kamil

+0

@ Kamil quale versione di python stai usando? e ho aggiunto la documentazione della mappa, tuttavia il modo più semplice per pensare a una 'map' in python è con questo' [A] => [B] ', dove la lunghezza di entrambe le liste (A e B) è la stessa, e la freccia rappresenta una modifica di ciascun elemento. Comunque puoi usare un for invece di esso, aggiungerò presto l'alternativa. –

+0

La persona che ha votato negativamente potrebbe dirmi il motivo? –