[英]Python lambda with 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表達式之外實例化?
我找不到有關它的任何文檔。
每次調用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
-comprehension { ... }
。
您正在對列表中的每個項目執行線性搜索-絕對不是最佳選擇。 對於擁有一百萬件商品的商店,帽子可以導致(1000000)²比較的順序,這甚至對於快速的計算機來說也是一個沉重的負擔。 那只是開始
要做的事情是用一個集合的ID創建一個集合,並使用集合的“ 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集-aas,這才有意義。
除此之外,如您所見,Python中的列表理解和生成器表達式具有一個if
子句,該子句取代了filter
函數的用法-僅當選擇使用功能符號而不是生成器/理解時, filter
才有意義-在大多數情況下將有一個額外的函數調用的開銷。
列表的編寫方式是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
這主要有兩件事可以提高效率:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.