如何解决围绕数字生成圆形图案的最简单方法 A.B.C.
我试图获取给定整数的所有周围整数,从实际整数开始,一次从两侧向外,例如:
generateNeighborhood(10,3)
,其中 10
是原点,3
是邻域的半径,应该返回 [10,11,9,12,8,13,7]
。
到目前为止我的尝试是这样的:
def generateNeighborhood(c: int,r: int):
yield c
for i in range(1,r + 1):
for j in range(2):
yield c + i * (-1) ** j
您知道实现这些结果的任何更简单的方法吗?
解决方法
这些都是我能想到的变体。如果您认为一个更好,请自行决定。问题是如果你想在循环的同一部分生成 1,-1 和 2,-2,你会得到一个嵌套列表。因此,您需要像我使用 itertools 一样将其展平。另外,在第一种方法中,0 生成了两次,因此我需要从索引 1 开始跳过一个 0。
def generateNeighborhoodA(c: int,r: int):
li = list(itertools.chain.from_iterable((-i,i) for i in range(r + 1)))
for i in range(1,len(li)):
yield li[i] + c
def generateNeighborhoodB(c: int,r: int):
yield c
for i in range(1,r + 1):
yield c + i
yield c - i
如果元素的顺序无关紧要,那就太短了。
,A.
这是一个简单的单行:
>>> c,r = 10,3
>>> sorted(range(c-r,c+r+1),key=lambda n: (abs(c-n),-n))
[10,11,9,12,8,13,7]
range()
可以轻松地为我们提供所需的数字,但要按正确的顺序排列,按每个距离中心 {{1}距离对每个数字进行排序}},使用 c
。并且要在该对中较小的邻居之前获得较大的邻居(11 比 9),请使用 abs()
,这对较大的邻居更负面(更小)。
如果您希望较小的邻居在较大的邻居之前,请翻转标志:
-n
在生成器中:
>>> sorted(range(c-r,n))
[10,7,13]
但是请注意 sorted()
returns a list 无论如何,因此也可以放置 def generateNeighborhood(c: int,r: int):
yield from sorted(range(c-r,-n))
。对于非常非常的列表(大半径 return sorted(...)
),使用 (B) 原始代码的修改版本或 (C >) 下面的变体:
B.
作为 user3386109 suggested in the comments,您可以删除 r
循环并生成该半径的邻居:
j
C.
这是一个带有生成器表达式的变体:
def generateNeighborhood(c: int,r + 1):
yield c + i
yield c - i
小半径和大半径的性能:
小:def generateNeighborhood(c: int,r: int):
yield c
pairs = ((c + i,c - i) for i in range(1,r + 1)) # generator,not expanded here
yield from (n for pair in pairs for n in pair) # processed one at a time
- B 比 A 快,比 C 快
- B:1.19 微秒
- A:2.53 微秒
- C:2.6 微秒
大:list(generateNeighborhood(10,3))
- B 比 C 快,比 A 快:
- B:877 毫秒
- C:1.43 秒
- 答:2.97 秒
所以为了简单起见,选择 A。为了速度,选择 B。(我认为 C 会击败 B,但事实并非如此。)
,一种有效的计算方法是矢量化操作。您可以使用 numpy 和 zip 函数来生成结果:
import numpy as np
def generateNeighborhood(c: int,r: int):
return np.hstack((np.array(c),np.array(list(zip(np.array(c) + np.array(range(1,r+1)),np.array(c) - np.array(range(1,r+1))))).ravel())).tolist()
使用 zip
组合周围的整数数组,使其按要求排列,然后与中心值水平堆叠。如果您不需要将结果作为列表,只需删除函数末尾的 .tolist()
。
这是一种使用 NumPy(或不使用 Numpy,如评论中所示)的巧妙方法。只需用注释中的列表推导式替换 pip install tensorflow-gpu==2.4
即可避免 numpy。-
np.arange
def generateNeighborhood(n,m):
#Get elements front and behind
f = np.arange(n+1,n+m+1) #[i for i in range(n+1,n+m+1)]
l = np.arange(n-m,n+1) #[i for i in range(n-m,n+1)]
#Alternating merge between 2 lists
result = [None]*(len(l)+len(f))
result[::2] = reversed(l)
result[1::2] = f
print(result)
generateNeighborhood(10,3)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。