- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
想象一个离散的 x,y,z 空间:我正在尝试创建一个迭代器,它将返回位于距某个点一定径向距离的球体内的所有点。
我的方法是首先查看一个更大的立方体中的所有点,保证包含所有需要的点,然后剔除或跳过距离太远的点。
我的第一次尝试是:
x,y,z=(0,0,1)
dist=2
#this doesn't work
it_0=((x+xp,y+yp,z+zp) for xp in range(-dist,dist+1) for yp in range(-dist,dist+1) for zp in range(-dist,dist+1) if ( ((x-xp)**2+(y-yp)**2+(z-zp)**2) <= dist**2+sys.float_info.epsilon ) )
一个简单的
for d,e,f in it_0:
#print(d,e,f)
print( ((x-d)**2+(y-e)**2+(z-f)**2) <= dist**2+sys.float_info.epsilon, d,e,f)
验证 it_0 没有产生正确的结果。我相信它仅将条件应用于第三个(即:z)“for”子句
以下作品:
it_1=((x+xp,y+yp,z+zp) for xp in range(-dist,dist+1) for yp in range(-dist,dist+1) for zp in range(-dist,dist+1))
it_2=filter( lambda p: ((x-p[0])**2+(y-p[1])**2+(z-p[2])**2) <= dist**2+sys.float_info.epsilon, it_1)
它收集所有的点,然后过滤那些不符合条件的点。
我希望有一种方法可以纠正第一次尝试的实现,或者使这些表达式更具可读性或更紧凑。
最佳答案
首先,我建议您将三重嵌套的 for
循环替换为 itertools.product()
,如下所示:
import itertools as it
it_1 = it.product(range(-dist, dist+1), repeat=3)
如果您使用的是 Python 2.x,则应在此处使用 xrange()
而不是 range()
。
接下来,您可以不使用 filter()
而只使用生成器表达式:
it_2=(x, y, z for x, y, z in it_1 if ((x-p[0])**2+(y-p[1])**2+(z-p[2])**2) <= dist**2+sys.float_info.epsilon)
这会避免 Python 2.x 中的一些开销(因为 filter()
构建了一个列表),但是对于 Python 3.x 来说是差不多的;甚至在 Python 2.x 中,您也可以使用 itertools.ifilter()
。
但为了可读性,我会将整个东西打包成一个生成器,如下所示:
import itertools as it
import sys
def sphere_points(radius=0, origin=(0,0,0), epsilon=sys.float_info.epsilon):
x0, y0, z0 = origin
limit = radius**2 + epsilon
for x, y, z in it.product(range(-radius, radius+1), repeat=3):
if (x**2 + y**2 + z**2) <= limit:
yield (x+x0, y+y0, z+z0)
我刚刚更改了您的原始代码。 x、y 和 z 的每个范围都被调整为以原点为中心。当我在半径为 0 的情况下测试此代码时,我正确地返回了一个点,即原点。
请注意,我为函数提供了参数,让您可以指定半径、原点,甚至是用于 epsilon 的值,每个参数都有默认值。我还将原点元组解包为显式变量;我不确定 Python 是否会优化索引操作,但这样我们就知道循环内不会进行任何索引操作。 (我认为 Python 编译器可能会将 limit
计算提升到循环之外,但实际上我更喜欢它单独一行,如此处所示,以提高可读性。)
我认为上面的代码与您用原生 Python 编写它的速度差不多,而且我认为它在可读性方面有了很大的改进。
附言如果使用 Cython 重做,这段代码可能会运行得更快。
编辑:按照@eryksun 在评论中的建议简化了代码。
关于具有多个 'for' 子句和单个 'if' 的 python 理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15603410/
我试图从一些 sql 查询中获得一些额外的性能,这些查询在一个字段上有一个 where 子句,它是一个非唯一的非聚集索引,它也是表 A 中的一个外键。该外键是主键在表 B 上,是聚集索引。 我想知道的
当包含在 FOR 中时,应该如何编写此 WMIC 命令脚本中的命令? wmic service where (name="themes" and state="running") get 下面的代码不
请帮我理解如何订购 对over子句的影响。我已经阅读了 msdn 和一本书,但仍然误解了。 假设我们有这样的查询: SELECT Count(OrderID) over(Partition By Ye
参见如下SQL语句: SELECT datediff("d", MAX(invoice.date), Now) As Date_Diff , MAX(invoice.date) AS ma
不知何故,对我来说构建这样的查询有点困难:给我所有链接名称不为空的导航条目 $query = $this->db->get_where('navigation',array('linkname'!==
我一直在寻找这个,但没有发现任何特别的东西。 是否可以有一个像 ALL IN 一样的 SQL 查询?为了更好地解释,这是一个表结构。 Orders table OrderItem table (hav
SELECT DISTINCT Campaign_id FROM Impressions WHERE Date BETWEEN '2015-03-01' AND '2015-03-31' ; 上述查询
我尝试在 MyBatis 中遵循 if 子句并得到以下异常请帮助我确定这里的问题.. public class Student{ private Integer studId; private Str
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我尝试在 MyBatis 中遵循 if 子句并得到以下异常请帮助我确定这里的问题.. public class Student{ private Integer studId; private Str
是否可以用 where in 子句做这样的事情,我需要使用 where in 查询以下数据。 select * FROM instructor AS i INNER JOIN teaches AS t
嗨,我怎样才能让这个查询工作。我想要一个关于 where 子句的条件,如果 @BACHNUMB = '',那么 WHERE 是 (h.sopnumbe = @SOPNUMBE) 否则 WHERE 是
我在 MVC3 项目中工作。我浏览了一段时间并尝试了几个示例,但无法正常工作。 我需要从 OrderForm 表中获取记录列表,其 DeptID 在我已经获得的另一个列表中。 我知道我需要使用 Con
select * from staff LEFT JOIN servicereservation on servicereservation.snic = staff.snic where servi
我正在尝试使用 MySQL 创建带有“WITH”子句的 View WITH authorRating(aname, rating) AS SELECT aname, AVG(quantity)
我正在尝试使用 MySQL 创建触发器,但遇到错误。限制是:用户不得对他或她同时销售的商品出价。 Create Trigger before_insert_bid Before Insert on B
我正在尝试在 PostgreSql 的 WHERE IN 子句中使用 split_part,如下所示。这里 Objcode 是 small int 类型,objection 可能像 1374,824,
这可能很简单,只是我太厚了 - 我试图阻止保留的元素在记录中被拾取,但只有当库存大于 0 时,我不知道该怎么做除非 "....WHERE blah blah AND (reserved = 0 OR
我总结了两个表中两列的行,即如下所示: SUM( tableA.age ) + sum( tableB.age) as 'Total Ages' 但在某些情况下,A表的结果为空,而B表的结果则不是。在
我写了一个查询,从出生日期字段开始计算出一个人的年龄,然后使用 AS age 创建一个年龄字段。 我的问题是,是否可以再次匹配那个年龄字段? 像这样, SELECT `candidates`.`can
我是一名优秀的程序员,十分优秀!