优化列表推导式

0 投票
5 回答
968 浏览
提问于 2025-04-16 01:19

这里有一段代码,我想对它进行优化:

result = [(item, foo(item))
          for item in item_list
          if cond1(item) and cond2(foo(item))]

在上面的代码中,我调用了 foo(item) 两次。我想不出一个方法,只遍历一次列表,同时保留 itemfoo(item),以便用于条件判断和结果列表。

也就是说,我希望在不重复遍历列表的情况下,保持 itemfoo(item) 的值,而不是调用 foo(item) 两次。

我知道可以通过第二个嵌套的列表推导来实现:

result = [(item, foo_item)
          for item, foo_item in [(i, foo(i)) for i in item_list]
          if cond1(item) and cond2(foo_item)]

但这样看起来会让 item_list 遍历两次,我想避免这种情况。

所以第一个例子是对每个列表项调用 foo 两次。第二个例子看起来是遍历列表两次。我希望只遍历一次,并且对每个项调用 foo 一次。

5 个回答

3

这个看起来怎么样?

result = [ (i, fi) for i  in item_list if cond1(i)
                   for fi in (foo(i),) if cond2(fi) ]
4

其实它并不会这样做,不过可以看看这里:

result = [(item, foo_item)
    for item, foo_item in ((i, foo(i)) for i in item_list)
    if cond1(item) and cond2(foo_item)]

把里面的列表推导式改成生成器表达式,可以确保我们不使用一个不必要的临时列表。

4

就像我在这里反复听到的,遇到这种情况最好的办法就是根本不要用列表推导式:

result = []
for item in item_list:
    if cond1(item):
        value = foo(item)
        if cond2(value):
            result.append((item, value))

不过我就是倔,还是想看看我能想出什么(等等——我把你的代码搞错了。不过,拆解一下并使用中间变量是避免重复调用的直接方法)

撰写回答