map()+lambda else子句如何不执行任何操作


map(lambda k,v: self._value_store.update(k=v) if self.keyword_check(k) == True else print('bad parameter'), kwargs.keys(),kwargs.value)

keyword_check(k)返回一个布尔值,具体取决于它是否在列表中。这样做的目的是基本上更新每个参数的字典值以及使用kwargs传递的值,但前提是参数名称存在于预定义列表中。

我不想使用for循环来解决这个问题。

我的问题是,else参数似乎是强制性的,但如果关键字验证返回TrueFalse,除了转到下一个可迭代之外,我不希望它做任何事情。我试着在else子句后面添加pass,但Python不喜欢。它可以使用我放置的else print('bad parameter'),但这只是一个临时解决方案。当它是False时,我可以在这里使用什么来真正做到什么都不做/什么都不输出?

注意,这个表达式实际上什么都不做(除了几处更正外,它与您的表达式相同,但为了可读性,它分布在几行上(:

map(lambda k,v: self._value_store.update((k,v)) # k=v always sets key 'k'
if self.keyword_check(k) == True
else print('bad parameter'),
kwargs.keys(),
kwargs.values()
)

map返回一个生成器。只有当您收集生成器的值时,它才会实际执行副作用(self._value_store.update(。因此,为了让它真正更新对象的内部值存储,你需要做一些类似的事情

list(map(lambda k,v: self._value_store.update((k,v))
if self.keyword_check(k) == True
else print('bad parameter'),
kwargs.keys(),
kwargs.values()
))

(您可以用all替换list,以避免创建一个无用的None列表;all在这里可以工作,因为{}.update()总是返回None,但这可能是更糟糕的编程风格。(

一般来说,只使用map来产生副作用通常不是一种好的风格,除非您确实需要延迟副作用的执行(在这种情况下,需要一些文档(。

相反,将生成器作为其第一个参数传递给updateupdate对其第一个参数进行迭代,因此生成器将被完全求值。此外,这个表达式更简单,(我认为(更容易阅读:

self._value_store.update((k,v) for k,v in kwargs.items()
if self.keyword_check(k))

你可能会发现一个显式循环更可读:

for k, v in kwargs.items():
if self.keyword_check(k):
self._value_store[k] = v
# Or, possibly faster (or possibly not):
for k in kwargs.keys():
if self.keyword_check(k):
self._value_store[k] = kwargs[k]    

顺便说一句,用True测试布尔函数返回的值是否相等也是一种反模式(这就是我上面没有做的原因(。如果谓词可能返回除True之外的真实值,则有忽略通过测试的值的风险。

正如其他人已经指出的,您的函数应该始终返回一个值(我不会对此进行争论(。

然而,也许你想要实现的是:

map(lambda k,v: self.keyword_check(k) and self._value_store.update(k=v), kwargs.keys(),kwargs.value)

请注意,我使用了一个简单的and运算符,而不是像您那样使用三元运算符。

这里,只有当self.keyword_check(k)True时,才调用方法self._value_store.update(k=v)。这就是你想要的(避免使用else子句(。

这要归功于短路求值:要求值AND表达式,如果第一个运算符为False,则表达式为False,并且不需要求值第二个运算符。

当然,您应该注意,如果第一个状态(self.keyword_check(k)(是False,那么返回值将是False(应该存在一个值(。

最新更新