gpt4 book ai didi

python - 在列表理解中的 if 语句中捕获方法

转载 作者:太空宇宙 更新时间:2023-11-03 12:55:45 25 4
gpt4 key购买 nike

我有以下用例:

[(x, f(x)) for x in list_x if f(x) == cond(x)]

上面的列表理解,我认为 f(x) 调用了两次?我如何避免这种情况并捕获 f(x) 的值,以便 f(x) 仅被调用一次。

我想,简单的解决方法是将上面的列表理解转换为 for 循环,但我很好奇是否可以使用列表理解有效地完成它。

最佳答案

您可以使用嵌套的生成器表达式只调用函数一次:

[(x, fx) for (x, fx) in ((x, f(x)) for x in list_x) if fx == cond(x)]

生成器表达式以锁步方式迭代以生成用于列表推导的 (x, fx) 元组。

如果你觉得这对读者来说更容易,你可以先将生成器表达式拆分成一个单独的名称:

mapped_x = ((x, f(x)) for x in list_x)
filtered_x = [(x, fx) for (x, fx) in mapped_x if fx == cond(x)]

重申这一点:生成器表达式是惰性执行的;对于 for ... in mapped_x 循环中的每一步,表达式中的 for 循环都是一步一步推进的。

演示:

>>> list_x = range(5)
>>> f = lambda x: print('f({!r})'.format(x)) or (x ** 2 - 1)
>>> cond = lambda x: print('cond({!r})'.format(x)) or x % 2 == 0
>>> mapped_x = ((x, f(x)) for x in list_x)
>>> [(x, fx) for (x, fx) in mapped_x if fx == cond(x)]
f(0)
cond(0)
f(1)
cond(1)
f(2)
cond(2)
f(3)
cond(3)
f(4)
cond(4)
[(1, 0)]

请注意 f(x) 是如何被调用一次,并立即检查条件的。

效率如何取决于 f(x) 调用的成本;生成器表达式作为单独的函数框架执行,解释器将在两个框架之间切换(列表推导的循环也是一个框架对象)。

如果 f(x) 是一个 Python 函数,您就已经赢了,因为您现在将创建的函数框架对象的数量减半(每个 f(x) 调用也会创建一个框架对象,创建这些对象的成本相对较高)。对于 C 函数,您应该使用 timeit module 创建一些试运行看看对于您预期的列表大小,什么更快。

关于python - 在列表理解中的 if 语句中捕获方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43178840/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com