تحديد جيران خلية ثنائية الأبعاد قائمة
سؤال
لدي قائمة من القوائم ، شيء من هذا القبيل
[[1, 2, 3,],[4, 5, 6,],[7, 8, 9]]
.
تمثيلها بيانيا كما يلي:
1 2 3
4 5 6
7 8 9
أنا أبحث عن أنيقة نهج التحقق من قيمة الجيران من الخلية أفقيا أو رأسيا قطريا.على سبيل المثال, جيران [0][2] هي [0][1], [1][1] و [1][2] أو الأرقام 2 و 5 و 6.
الآن أنا أدرك أنني قد لا مجرد bruteforce الهجوم التحقق من كل قيمة a la:
[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]
ولكن هذا سهل و فكرت يمكن معرفة المزيد من خلال رؤية بعض أكثر أناقة النهج.
المحلول
# 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)]
أنا لا أعرف إذا كان هذا يعتبر نظيفة, ولكن هذا واحد-بطانة يعطيك كل الجيران قبل بالتكرار عليها ونبذ أي حافة الحالات.
نصائح أخرى
ميغابايت ...
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:])
وعلى افتراض لديك مصفوفة مربعة:
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
itertools.product
و بفضل <لأ href = بايثون "https://docs.python.org/2/reference/expressions.html#yield-expressions" يختلط = "noreferrer"> تسفر عن التعبير و <لأ href = "https://docs.python.org /2/tutorial/controlflow.html#unpacking-argument-lists "يختلط =" noreferrer "> نجمة مشغل ، وظيفة جميلة <لأ href =" https://en.wikipedia.org/wiki/Don ٪ 27t_repeat_yourself "يختلط =" noreferrer "> الجافة ولكن لا تزال قابلة للقراءة بما فيه الكفاية.
وبالنظر إلى حجم مصفوفة 3، يمكنك بعد ذلك (إذا لزم الأمر) جمع الجيران في list
:
>>> list(neighbours((2,2)))
[(1, 1), (1, 2), (2, 1)]
وماذا يفعل وظيفة يمكن تصور كما يلي:
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
ولا توجد طريقة أنظف للقيام بذلك. إذا كنت تريد حقا هل يمكن إنشاء دالة:
def top(matrix, x, y):
try:
return matrix[x][y - 1];
except IndexError:
return None
إذا كان شخص ما غريبة عن طريقة بديلة لنقل المباشر (غير قطري) الجيران، وهنا تذهب:
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))]
وفيما يلي القائمة:
(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)
وحتى الجيران الأفقي (س، ص) هي (س + 1، ص).
والجيران الرأسي و(س، ص +/- 1).
والجيران قطري و(خ +/- 1، ص +/- 1).
وتنطبق هذه القواعد على مصفوفة لانهائية. للتأكد من الجيران تنسجم مع مصفوفة محدودة، إذا كان الأولي (س، ص) هو في الحافة، مجرد تطبيق واحد أكثر التقييد على إحداثيات الجيران - حجم المصفوفة
>>> 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]
وأنا لا أعرف كيف أنيقة يبدو لكم، ولكن يبدو أن العمل ث / س أي يصعب الترميز.
وهذا يولد جميع المؤشرات:
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]
وربما تقوم بالتدقيق مربع سودوكو. إذا كان المربع ن خ ن والخلية الحالية هي (س، ص) بدء التحقق:
startingRow = x / n * n;
startingCol = y/ n * n
JS_is_bad للحصول على تلميح كبير عن جيرانها. هنا هو رمز لتشغيل هذه المشكلة
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 []
إذا lambdas أرعب كنت هنا كنت lambdas. ولكنها تجعل نظرة الشفرة نظيفة. @ johniek_comp لديه حل نظيفة جدا 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))