Python lambda与列表理解

时间:2016-06-21 13:05:27

标签: python python-2.7 lambda list-comprehension

我对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表达式之外实例化?

我找不到任何关于它的文档。

3 个答案:

答案 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

这有两个主要方面可以提高效率:

  1. 它创建一个集合,用于快速成员资格检查
  2. 它将lambda / filter组合替换为更高效的理解。