我对lambda表达式有内部列表理解操作的疑问。
在下面的代码中,lambda每次都会为每个项目实例化一个列表?
def _find_items_not_present_in_store(self, store_today, store_yesterday):
# finding what items are not in the store anymore
items_not_in_store_anymore = filter(lambda item1: item1.item_id not in
[item2.item_id for item2 in store_today.store_items],
store_yesterday)
return items_not_in_store_anymore
将此列表更好
[item2.item_id for item2 in store.store_items]
在lambda表达式之外实例化?
我找不到任何关于它的文档。
答案 0 :(得分:1)
lambda
函数的每次调用都会重新创建该列表,因此将该结构移到lambda
之外会提高性能。
此外,使用list
检查in
并不是一个好主意,因为它需要线性时间。请考虑使用set
代替:
def _find_items_not_present_in_store(self, store_today, store_yesterday):
today_ids = {item2.item_if for item2 in store_today.store_items}
items_not_in_store_anymore = filter(
lambda item1: item1.item_id not in today_ids,
store_yesterday
)
return items_not_in_store_anymore
在旧版本的python中,你需要set( ... )
而不是set
- 理解{ ... }
。
答案 1 :(得分:1)
您正在对列表中的每个项目执行线性搜索 - 这绝对不是最佳选择。对于有库存100万件商品的商店,帽子可以达到(1000000)²比较的顺序,这对于快速计算机来说也是一个相当大的负担。那只是为了开始
要做的是创建一个具有其中一个集合的ID的集合,并使用set的“contains”(相同的in
运算符) - 它在恒定时间内搜索。
def _find_items_not_present_in_store(self, store_today, store_yesterday):
yesterday_ids = set(item.item_id for item in store_yesterday)
return [item for item in store_today if item.item_id not in yesterday_ids]
而且 - 在你的代码中 - 除了在列表中搜索而不是在一个集合中,你实际上正在重新创建今天列表中每个项目的整个昨天的ID列表 - 作为列表生成器表达式在lambda函数内部。在上面的方法中,我只预先计算一次ID集 - 这是有意义的。
除此之外,正如您所看到的,Python中的列表推导和生成器表达式有if
子句取代filter
函数的使用 - filter
只有在选择时才有意义使用函数符号而不是生成器/理解 - 并且在大多数情况下将有一个额外函数调用的开销。
答案 2 :(得分:1)
你编写它的方式,列表是lambda表达式的一部分,因此每次调用lambda时都会对它进行求值。
这是实现功能的最有效方式:
def _find_items_not_present_in_store(self, store_today, store_yesterday):
s = set(item2.item_id for item2 in store_today.store_items)
items_not_in_store_anymore = [item1 for item1 in store_yesterday
if item1.item_id not in s]
return items_not_in_store_anymore
这有两个主要方面可以提高效率: