Frage

Ich habe eine Liste von Listen, so etwas wie

[[1, 2, 3,],[4, 5, 6,],[7, 8, 9]].

Grafisch dargestellt als:

1 2 3
4 5 6
7 8 9

Ich bin auf der Suche nach einem eleganten Ansatz, um den Wert von Nachbarn einer Zelle überprüft, horizontal, vertikal und diagonal. Zum Beispiel ist die Nachbarn von [0] [2] [0] [1], [1] [1] und [1] [2] oder die Zahlen 2, 5, 6

Nun Ich weiß, ich könnte nur einen Brute-Force-Angriff zu tun jeden Wert a la Überprüfung:

[i-1][j]
[i][j-1]
[i-1][j-1]
[i+1][j]
[i][j+1]
[i+1][j+1]
[i+1][j-1]
[i-1][j+1]

Aber das ist einfach, und ich dachte, ich kann mehr lernen, indem sie einige elegantere Ansätze zu sehen.

War es hilfreich?

Lösung

# Size of "board"
X = 10
Y = 10

neighbors = lambda x, y : [(x2, y2) for x2 in range(x-1, x+2)
                               for y2 in range(y-1, y+2)
                               if (-1 < x <= X and
                                   -1 < y <= Y and
                                   (x != x2 or y != y2) and
                                   (0 <= x2 <= X) and
                                   (0 <= y2 <= Y))]

>>> print(neighbors(5, 5))
[(4, 4), (4, 5), (4, 6), (5, 4), (5, 6), (6, 4), (6, 5), (6, 6)]

Ich weiß nicht, ob diese sauber betrachtet wird, aber diese Einzeiler gibt Ihnen alle Nachbarn über sie iterieren und alle Grenzfälle zu verwerfen.

Andere Tipps

mb ...

from itertools import product, starmap

x, y = (8, 13)
cells = starmap(lambda a,b: (x+a, y+b), product((0,-1,+1), (0,-1,+1)))

// [(8, 12), (8, 14), (7, 13), (7, 12), (7, 14), (9, 13), (9, 12), (9, 14)]
print(list(cells)[1:])

Angenommen, Sie eine quadratische Matrix hat:

from itertools import product

size = 3

def neighbours(cell):
    for c in product(*(range(n-1, n+2) for n in cell)):
        if c != cell and all(0 <= n < size for n in c):
            yield c

Mit itertools.product und dank Python ergeben Ausdruck und Sternoperator , die Funktion ist ziemlich trocken aber noch lesbar genug.

eine Matrixgröße von 3 gegeben, können Sie dann (falls erforderlich) sammeln die Nachbarn in einem list:

>>> list(neighbours((2,2)))
[(1, 1), (1, 2), (2, 1)]

Was die Funktion macht kann sichtbar gemacht werden, wie folgt:

 Funktion Visualisierung

for x_ in range(max(0,x-1),min(height,x+2)):
  for y_ in range(max(0,y-1),min(width,y+2)):
    if (x,y)==(x_,y_): continue
    # do stuff with the neighbours

>>> a=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> width=height=3
>>> x,y=0,2
>>> for x_ in range(max(0,x-1),min(height,x+2)):
...   for y_ in range(max(0,y-1),min(width,y+2)):
...     if (x,y)==(x_,y_): continue
...     print a[x_][y_]
... 
2
5
6

Es gibt keinen sauberen Weg, dies zu tun. Wenn Sie wirklich wollen Sie eine Funktion erstellen können:

def top(matrix, x, y):
     try:
         return matrix[x][y - 1];
     except IndexError:
         return None

Wenn jemand neugierig auf alternative Art und Weise ist die direkten (nicht diagonal) Nachbarn zu holen, hier gehen Sie:

neighbors = [(x+a[0], y+a[1]) for a in 
                    [(-1,0), (1,0), (0,-1), (0,1)] 
                    if ( (0 <= x+a[0] < w) and (0 <= y+a[1] < h))]

Hier ist die Liste:

(x - 1, y - 1) (x, y - 1) (x + 1, y - 1)
(x - 1, y)     (x, y)     (x + 1, y)
(x - 1, y + 1) (x, y + 1) (x + 1, y + 1)

So die horizontalen Nachbarn von (x, y) (x +/- 1, y).

Die vertikalen Nachbarn sind (x, y +/- 1).

diagonale Nachbarn sind (x +/- 1, +/- y 1).

Diese Regeln gelten für eine unendliche Matrix. Um sicherzustellen, dass die Nachbarn passen in eine endliche Matrix, wenn die anfängliche (x, y) an der Kante ist, gelten nur eine weitere Beschränkung auf den Koordinaten der Nachbarn. - Die Matrixgröße

>>> import itertools
>>> def sl(lst, i, j):
    il, iu = max(0, i-1), min(len(lst)-1, i+1)
    jl, ju = max(0, j-1), min(len(lst[0])-1, j+1)
    return (il, iu), (jl, ju)

>>> lst = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> tup = 0, 2
>>> [lst[i][j] for i, j in itertools.product(*sl(lst, *tup)) if (i, j) != tup]
[2, 5, 6]

Ich weiß nicht, wie elegant es dir scheint, aber es scheint, w / o zu arbeiten jede Hartcodierung.

Dies erzeugt alle Indizes:

def neighboring( array ):
    nn,mm = len(array), len(array[0])
    offset = (0,-1,1) # 0 first so the current cell is the first in the gen
    indices = ( (i,j) for i in range(nn) for j in range(mm) )
    for i,j in indices:
        all_neigh =  ( (i+x,j+y) for x in offset for y in offset )
        valid = ( (i,j) for i,j in all_neigh if (0<=i<nn) and (0<=j<mm) ) # -1 is a valid index in normal lists, but not here so throw it out
        yield valid.next(), valid ## first is the current cell, next are the neightbors

for (x,y), neigh in neighboring( l ):
    print l[x][y], [l[x][y] for x,y in neigh]

vielleicht bist gerade Sie ein Sudoku-Box. Wenn die Box n x n und aktuelle Zelle ist (x, y) beginnt Überprüfung:

startingRow = x / n * n;
startingCol = y/ n * n

Dank @JS_is_bad für große Andeutung über die Nachbarn. hier ist der laufende Code für dieses Problem

    def findNeighbours(l,elem):
    #This try is for escaping from unbound error that happens 
    #when we try to iterate through indices that are not in array
    try:
        #Iterate through each item of multidimensional array using enumerate
        for row,i in enumerate(l):
            try:
                #Identifying the column index of the givem element
                column=i.index(elem)
            except ValueError:
                continue
            x,y=row,column

    #    hn=list(((x,y+1),(x,y-1))) #horizontal neighbours=(x,y+/-1)
    #    vn=list(((x+1,y),(x-1,y))) #vertical neighbours=(x+/-1,y)
    #    dn=list(((x+1,y+1),(x-1,y-1),(x+1,y-1),(x-1,y+1))) #diagonal neighbours=(x+/-1,y+/-1)
        #Creating a list with values that are actual neighbors for the extracted index of array
        neighbours=[(x,y+1),(x,y-1),(x+1,y),(x-1,y),(x+1,y+1),(x-1,y-1),(x+1,y-1),(x-1,y+1)]
        #Creating a universe of indices from given array
        index_list=[(i,j) for i in range(len(l)) for j in range(len(l[i]))]
        #Looping through index_list and nested loop for neighbours but filter for matched ones
        # and extract the value of respective index
        return_values=[l[index[0]][index[1]] for index in index_list for neighbour in neighbours if index==neighbour]
        return return_values,neighbours
    except UnboundLocalError:
        return []

Wenn lambdas Sie hier schrecken Sie sind .Aber lambdas Ihr Code aussehen sauber machen. @ Johniek_comp hat eine sehr saubere Lösung TBH

k,l=(2,3)
x = (0,-1,+1)
y = (0,-1,+1)
cell_u = ((k+a,l+b) for a in x for b in y)
print(list(cell_u))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top