2013-02-04 9 views
5

Ho una funzione all'interno di una classe Python (2.7) che dovrebbe recuperare i valori delle "celle" attorno ad esso in una matrice numpy bidimensionale. Se l'indice non è compreso nell'intervallo, il valore dovrebbe essere impostato su Nessuno.Imposta nessuno se non esiste l'indice di array numpy

Sto faticando a trovare un modo per farlo senza scrivere 8 istruzioni try/catch, o senza utilizzare più se x altrimenti le istruzioni Nessuna come è nel mio codice qui sotto. Mentre entrambi lavorerebbero, non sembrano molto ben strutturati, e penso che ci sia un modo più semplice per farlo: probabilmente mi sono preso la briga di pensare a questo in modo completamente sbagliato. Qualsiasi aiuto sarebbe molto apprezzato.

# This will return a dictionary with the values of the surrounding points 
def get_next_values(self, column, row): 
    if not (column < self.COLUMNS and row < self.ROWS): 
     print "Invalid row/column." 
     return False 

    nextHorizIsIndex = True if column < self.COLUMNS - 2 else False 
    nextVertIsIndex = True if row < self.ROWS - 2 else False 

    n = self.board[column, row-1] if column > 0 else None 
    ne = self.board[column+1, row-1] if nextHorizIsIndex else None 
    e = self.board[column+1, row] if nextHorizIsIndex else None 
    se = self.board[column+1, row+1] if nextHorizIsIndex and nextVertIsIndex else None 
    s = self.board[column, row+1] if nextVertIsIndex else None 
    sw = self.board[column-1, row+1] if nextVertIsIndex else None 
    w = self.board[column-1, row] if row > 0 else None 
    nw = self.board[column-1, row-1] if 0 not in [row, column] else None 

    # debug 
    print n, ne, e, se, s, sw, w, nw 
+1

Attenzione per l'indice negativo avvolgente ...! – wim

+0

Non mi era venuto in mente, grazie! – Adam

risposta

5

Ecco un trucco standard: creare la scheda con uno spigolo con il valore Nessuno. Quindi è possibile accedere a qualsiasi quadrato 3x3 interno e riempire i valori appropriati con

nw, n, ne, w, _, e, sw, s, se = (self.board[column-1:column+2, row-1:row+2]).ravel() 

Ad esempio,

import numpy as np 

board = np.empty((10,10), dtype = 'object') 
board[:,:] = None 
board[1:9, 1:9] = np.arange(64).reshape(8,8) 
print(board) 
# [[None None None None None None None None None None] 
# [None 0 1 2 3 4 5 6 7 None] 
# [None 8 9 10 11 12 13 14 15 None] 
# [None 16 17 18 19 20 21 22 23 None] 
# [None 24 25 26 27 28 29 30 31 None] 
# [None 32 33 34 35 36 37 38 39 None] 
# [None 40 41 42 43 44 45 46 47 None] 
# [None 48 49 50 51 52 53 54 55 None] 
# [None 56 57 58 59 60 61 62 63 None] 
# [None None None None None None None None None None]] 

column = 1 
row = 1 
nw, n, ne, w, _, e, sw, s, se = (board[column-1:column+2, row-1:row+2]).ravel() 
print(nw, n, ne, w, _, e, sw, s, se) 
# (None, None, None, None, 0, 1, None, 8, 9) 

noti che

  • Quando si definisce il bordo di questo modo , il primo indice non-None è ora 1, non 0.
  • Penso che sia più tipico Al pensare al primo indice come la riga, e il secondo indice come colonna, perché quando si print(board) è il modo in cui i valori sono formattati. Quindi forse vuoi board[row-1:row+2, column-1:column+2] invece. Ovviamente, è possibile definire la propria funzione print_board e quindi essere liberi di utilizzare qualsiasi convenzione si desideri.
+0

Un buon trucco, ma potrebbero avere problemi ad usare 'Nessuno' in un array con dtype numerico. Potrebbe dover usare dtype 'object', che non è molto" numpythonic ", o usare' nan' invece di 'None'. – wim

+0

È vero che 'nan' potrebbe essere una scelta migliore se il dtype è mobile. – unutbu

+0

Grazie! Questo è davvero utile - non ero a conoscenza della sintassi 'board [:,:] = None'. Il mio dtype è int, quindi lo proverò con il 'nan'. – Adam