我从this回答了代码
for i in userInput:
if i in wordsTask:
a = i
break
可以通过以下方式编写为列表推导:
next([i for i in userInput if i in wordsTask])
我有一个类似的问题,就是我想在列表理解方面编写以下(从原始问题简化)代码:
for i in xrange(N):
point = Point(long_list[i],lat_list[i])
for feature in feature_list:
polygon = shape(feature['geometry'])
if polygon.contains(point):
new_list.append(feature['properties'])
break
我希望每个point
与功能列表中的单个多边形相关联。因此,一旦找到包含该点的多边形,break
将用于移动到下一个点。因此,new_list
将具有完全N
元素。
我把它写成列表理解如下:
new_list = [feature['properties'] for i in xrange(1000) for feature in feature_list if shape(feature['geometry']).contains(Point(long_list[i],lat_list[i])]
当然,这并没有考虑break
语句中的if
,因此比使用嵌套for循环花费的时间要长得多。使用上面链接的帖子(我可能不完全理解)的建议,我做了
new_list2 = next(feature['properties'] for i in xrange(1000) for feature in feature_list if shape(feature['geometry']).contains(Point(long_list[i],lat_list[i]))
但是,new_list2
的元素少于N个(在我的例子中,N=1000
和new_list2
只有5个元素)
问题1:作为列表理解,是否值得这样做?唯一的原因是我读到列表理解通常比嵌套for循环快一点。每秒有200万个数据点。
问题2:如果是这样,我如何将break
语句纳入列表理解?
问题3:以我的方式使用next
时出现的错误是什么?
非常感谢你的时间和善意的帮助。
答案 0 :(得分:3)
列表推导不一定比for
循环更快。如果你有一个类似的模式:
some_var = []
for ...:
if ...:
some_var.append(some_other_var)
然后是的,列表理解比一堆.append()
更快。但是,你有情有可原的情况。首先,在next(...)
的情况下,它实际上是一个生成器表达式,因为它周围没有[
和]
。
.append()
)。你只是得到一个价值。Point(long_list[i], lat_list[i])
中的每个i
的每个功能调用xrange(N)
一次,而循环仅为每个i
调用一次。为什么你的发电机表达不起作用?因为它只找到整体的第一个值。另一方面,循环查找每个i
的第一个值。你看到了区别?生成器表达式从两个循环中断开,但for
循环仅突破内部循环。
如果您希望性能稍有改善,请使用{3}中的itertools.izip()
(或仅zip()
):
from itertools import izip
for long, lat in izip(long_list, lat_list):
point = Point(long, lat)
...
答案 1 :(得分:2)
我不知道复杂的列表推导或生成器表达式比嵌套循环快得多,如果它们运行相同的算法(例如访问相同数量的值)。要获得明确的答案,您应该尝试以两种方式实施解决方案并进行测试,以确定哪种方法对您的实际数据更快。
至于如何使内循环而不是外循环短路,你需要将next
调用放在主列表理解中,并在其中包含一个单独的生成器表达式:< / p>
new_list = [next(feature['properties'] for feature in feature_list
if shape(feature['shape']).contains(Point(long, lat)))
for long, lat in zip(long_list, lat_list)]
我改变了另外一件事:而不是使用long_list
使用lat_list
进行迭代,使range
和zip
的索引编入索引他们并行。
请注意,如果反复创建Point
个对象需要花费太多时间,可以通过添加另一个创建点的嵌套生成器表达式来简化代码的这一部分,并允许您将它们绑定到(可重复使用)名称:
new_list = [next(feature['properties'] for feature in feature_list
if shape(feature['shape']).contains(point))
for point in (Point(long, lat) for long, lat in zip(long_list, lat_list))]