Python 搜索列表并递增的Lambda

Python 搜索列表并递增的Lambda,python,lambda,Python,Lambda,使用Pythonlambda可以检查元素是否存在于另一个列表(映射)中并增加一个变量吗?我正试图使用lambda优化/重构我的代码,但我自己也弄糊涂了 下面是我要转换为lambda的现有代码。是否可以使用一个lambda或我需要使用两个lambda?有什么建议吗?如何将其转换为lambda/s current_orders = auth.get_orders() # returns [{'id': 'foo', 'price': 1.99, ...}, ...] deleted_orders

使用Python
lambda
可以检查元素是否存在于另一个列表(映射)中并增加一个变量吗?我正试图使用lambda优化/重构我的代码,但我自己也弄糊涂了

下面是我要转换为lambda的现有代码。是否可以使用一个lambda或我需要使用两个lambda?有什么建议吗?如何将其转换为lambda/s

current_orders = auth.get_orders() 
# returns [{'id': 'foo', 'price': 1.99, ...}, ...]

deleted_orders = auth.cancel_orders() 
# returns id's of all cancelled orders [{'id': 'foo'}, {'id': 'bar'}, ...]


# Attempting to convert to lambda
n_deleted = 0
for del_order in deleted_orders:
    for order in current_orders:
        if del_order['id'] == order['id']:
            n_deleted += 1

# lambda
n_deleted = filter(lambda order, n: n += order['id'] in current_orders, deleted_orders)
# end


if n_deleted != len(orders):
    logger.error("Failed to cancel all limit orders")

注意:我知道我可以说
如果len(已删除的订单)
,但我想扩展我的lambda最终说
…:logger.error(“未能删除ID为:%s的订单”)

可以绕过它,但
lambda
s不应该变异,他们应该返回一个新结果。此外,您不应过度复杂化
lambda
s,它们用于短而快速的功能,例如
用于
排序
方法

可以绕过它,但
lambda
s不应突变,它们应返回新结果。此外,您不应过度复杂化
lambda
s,它们是用于短而快速的功能,例如
用于
排序
方法

您根本不能在
lambda
中使用
+=
(或任何类型的赋值),并且使用
过滤器
进行副作用是一个可怕的主意(这个模式看起来有点像
reduce
是如何使用的,但是很难判断您正在尝试做什么)

看起来您正在尝试计算订购['id']的
数量
值出现在
当前\u订单中
。您根本不应该为此使用
lambda
。为了提高效率,请将
id
作为
集合
从中取出,并使用
集合
操作检查是否在两个
列表中都找到了所有
id

from future_builtins import map  # Only on Py2, to get generator based map
from operator import itemgetter


... rest of your code ...

getid = itemgetter('id')
# Creating the `set`s requires a single linear pass, and comparison is
# roughly linear as well; your original code had quadratic performance.
if set(map(getid, current_orders)) != set(map(getid, deleted_orders)):
    logger.error("Failed to cancel all limit orders")
如果您想知道哪些订单没有取消,可以稍微调整一下,将
If
检查和
logger
输出替换为:

for oid in set(map(getid, current_orders)).difference(map(getid, deleted_orders)):
    logger.error("Failed to cancel order ID %s", oid)
如果要按
oid
对错误日志进行排序,请将
集合进行包装。差异
调用
排序
,如果要按
当前\u订单
中返回的相同顺序进行排序,请更改为:

from itertools import filterfalse  # On Py2, it's ifilterfalse

# Could inline deletedids creation in filterfalse if you prefer; frozenset optional
deletedids = frozenset(map(getid, deleted_orders))  
for oid in filterfalse(deletedids.__contains__, map(getid, current_orders)):
    logger.error("Failed cancel order ID %s", oid)

你根本不能在
lambda
中使用
+=
(或任何类型的赋值),而使用
过滤器
处理副作用是一个糟糕的主意(这种模式看起来有点像
reduce
的使用方式,但很难说你在尝试做什么)

看起来您正在尝试计算订购['id']的
数量
值出现在
当前\u订单中
。您根本不应该为此使用
lambda
。为了提高效率,请将
id
作为
集合
从中取出,并使用
集合
操作检查是否在两个
列表中都找到了所有
id

from future_builtins import map  # Only on Py2, to get generator based map
from operator import itemgetter


... rest of your code ...

getid = itemgetter('id')
# Creating the `set`s requires a single linear pass, and comparison is
# roughly linear as well; your original code had quadratic performance.
if set(map(getid, current_orders)) != set(map(getid, deleted_orders)):
    logger.error("Failed to cancel all limit orders")
如果您想知道哪些订单没有取消,可以稍微调整一下,将
If
检查和
logger
输出替换为:

for oid in set(map(getid, current_orders)).difference(map(getid, deleted_orders)):
    logger.error("Failed to cancel order ID %s", oid)
如果要按
oid
对错误日志进行排序,请将
集合进行包装。差异
调用
排序
,如果要按
当前\u订单
中返回的相同顺序进行排序,请更改为:

from itertools import filterfalse  # On Py2, it's ifilterfalse

# Could inline deletedids creation in filterfalse if you prefer; frozenset optional
deletedids = frozenset(map(getid, deleted_orders))  
for oid in filterfalse(deletedids.__contains__, map(getid, current_orders)):
    logger.error("Failed cancel order ID %s", oid)

也许你应该使用列表理解

current_order_ids = {order['id'] for order in current_orders}
not_del = [order for order in deleted_orders if order['id'] not in current_order_ids]

for order in not_del:
    logger.error("Failed to delete ORDER with ID: %s", order['id'])

也许你应该使用列表理解

current_order_ids = {order['id'] for order in current_orders}
not_del = [order for order in deleted_orders if order['id'] not in current_order_ids]

for order in not_del:
    logger.error("Failed to delete ORDER with ID: %s", order['id'])

lambda
是为实现一个简单的单行函数而设计的。如果您需要多行函数来完成功能,请使用
def
创建一个函数。理想情况下
lambda
函数不应有副作用
lambda
是为实现一个简单的单行函数而设计的。如果您需要多行函数要完成您的功能,请使用
def
创建一个功能。理想情况下
lambda
功能不应该有副作用是真的,但我想我可以在两个lambda中完成这一点,你不这样认为吗?一个lambda(a)搜索两个地图列表,寻找相同的“id”,然后搜索另一个(b)如果
a
返回true/1,则增加一个值?即nest lambdas?@JakeM:
lambda
s只是有限用途的匿名函数。它们可以做很多事情,但它们有限、难看,通常是解决任何给定问题的最糟糕方法。你有一把锤子,你把一切都当作钉子。用正确的方法解决问题顺便说一句,不要一直试图把它放在一个可笑的复杂的
lambda
解决方案中。是的,没错,但我想我可以用两个lambda来实现这一点,你不这么认为吗?一个lambda(a)搜索两个地图列表中的同一个“id”,然后另一个(b)如果
a
返回true/1,则增加一个值?即nest lambdas?@JakeM:
lambda
s只是有限用途的匿名函数。它们可以做很多事情,但它们有限、难看,通常是解决任何给定问题的最糟糕方法。你有一把锤子,你把一切都当作钉子。用正确的方法解决问题顺便说一句,不要一直试图把它放在一个可笑的复杂的
lambda
解决方案中。我想你已经把它倒过来了,OP感兴趣的是没有取消的当前订单,而不是根本没有订单的取消订单(尽管我认为两者都是错误,OP的逻辑检测它们是等价的)。此外,您可以将括号更改为parens以跳过listcomp,并使用genexpr来避免临时的
列表
(假设结果仅迭代一次)。我认为您可以将其反向设置,OP感兴趣的是未取消的当前订单,而不是根本不是订单的已取消订单(虽然我认为这两个都是错误,OP的逻辑会同等地检测它们)。此外,您可以将括号更改为parens以跳过listcomp,并使用genexpr来避免临时的
列表(假设结果只迭代一次)。