Python Dict理解、元组与惰性评价
我想看看我是否能在Python中实现一些相当懒惰的东西 我有一个dict理解,其中值是一个元组。我希望能够使用元组的第一个条目创建元组的第二个条目 举个例子应该会有所帮助Python Dict理解、元组与惰性评价,python,python-3.x,dictionary,functional-programming,Python,Python 3.x,Dictionary,Functional Programming,我想看看我是否能在Python中实现一些相当懒惰的东西 我有一个dict理解,其中值是一个元组。我希望能够使用元组的第一个条目创建元组的第二个条目 举个例子应该会有所帮助 dictA = {'a': 1, 'b': 3, 'c': 42} {key: (a = someComplexFunction(value), moreComplexFunction(a)) for key, value in dictA.items()} moreComplexFunction是否可能在元组的第一个条目中
dictA = {'a': 1, 'b': 3, 'c': 42}
{key: (a = someComplexFunction(value), moreComplexFunction(a)) for key, value in dictA.items()}
moreComplexFunction
是否可能在元组的第一个条目中使用计算 您可以在一个元素元组上添加第二个循环:
{key: (a, moreComplexFuntion(a)) for key, value in dictA.items()
for a in (someComplexFunction(value),)}
这使您可以访问值表达式中的someComplexFunction(value)
的输出,但这相当难看
就我个人而言,在这种情况下,我会转向常规循环:
dictB = {}
for key, value in dictA.items():
a = someComplexFunction(value)
dictB[key] = (a, moreComplexFunction(a))
或者,您可以编写一个函数来返回元组:
def kv_tuple(a):
tmp = someComplexFunction(a)
return (a, moreComplexFunction(tmp))
{key:kv_tuple(value) for key, value in dictA.items()}
这也让您可以选择使用namedtuple之类的东西来获取元组项的名称,等等。我不知道这会快多少/慢多少。。。常规循环可能会更快(函数调用更少).此外,使用生成器表达式和dict理解也是非常语义和惰性的:
dictA = { ... } # Your original dict
partially_computed = ((key, someComplexFunction(value))
for key, value in dictA.items())
dictB = {key: (a, moreComplexFunction(a)) for key, a in partially_computed}
Martijn,谢谢。这似乎是一个合理的事情想做(至少对我来说)。显然,为了清晰起见,循环更好。如果有一个聪明的语言功能,我可以利用它来实现这一点,那就太好了。:)我的+1用于常规循环。代码更简单、更高效。聪明的语言功能是“lambda函数”,它是函数式编程工具套件的一部分,可以让您嵌入该函数,即{key:(lambda x:(x,moreComplexFunction(x)))(someComplexFunction(value)),对于key,value in dictA.items()}。但它更难看,更难阅读,速度也更慢。循环很容易阅读并且可能是最快的。您可以让
someComplexFunction
实现一个,然后只需调用moreComplexFunction(someComplexFunction(value))
,就不会影响性能。缓存中有一些开销,如果只使用一次缓存,可能会有过大的杀伤力,因此我将此作为一个注释而不是答案。这只是引入额外循环的另一种形式:-)@MartijnPieters这正是我所想的!为什么是的,是的,它是>。你知道,这就是我最终要做的,但我想要的东西是使用Python函数式编程模型的一个简洁功能。@fgnu:创建一个函数只是为了使用理解会损害效率,而且会使人困惑。只需将循环放在函数中。@eryksun-它可能会混淆,也可能更简单。对我来说,缩短语句可以让我更容易阅读(就像我说的,我更喜欢在这里命名tuple)kv_tuple
不是一个很有描述性的名称,但我不知道它用于什么。。。可以很容易地给它一个名称,这样上面的语句就可以更清楚地从dictA中的Y数据生成X数据(以及一个更容易阅读的函数包装)。除非有充分的理由在代码的其他地方使用kv\u tuple
,否则我同意,我可能也会使用循环。不,我绝对同意它的速度较慢。。。。只是这并不一定很难理解。我第一次评论中的斜体字暗示这将是一个一次性使用的函数。这就是为什么我建议将循环移动到显式函数中——如果目的是让代码更容易理解的话。然后,可以在表达式中调用该函数,就像使用理解一样。