在循环中追加/扩展列表

时间:2011-09-11 16:44:43

标签: python

我希望在循环时扩展一个列表:

for idx in xrange(len(a_list)):
    item = a_list[idx]
    a_list.extend(fun(item))

(fun是一个返回列表的函数。)

问题:
这是否是最好的方法,或者更好,更紧凑的可能性?

说明:

from matplotlib.cbook import flatten
a_list.extend(flatten(fun(item) for item in a_list))

应该可以工作,但我不希望我的代码依赖于matplotlib。

for item in a_list:
    a_list.extend(fun(item))

对我来说会很好,但似乎会导致无限循环。

上下文:
我有很多节点(在一个字典中),其中一些是特殊的,因为它们在边界上。 'a_list'包含这些特殊/边界节点的键。有时添加节点,然后需要将边界上的每个新节点添加到'a_list'。新的边界节点可以由旧的边界节点确定(这里用'fun'表示),每个边界节点可以添加几个新的节点。

4 个答案:

答案 0 :(得分:2)

使用itertools,可以写成:

import itertools
a_list += itertools.chain(* itertools.imap(fun, a_list))

或者,如果你的目标是代码高尔夫:

a_list += sum(map(fun, a_list), [])

或者,只需写出来:

new_elements = map(fun, a_list) # itertools.imap in Python 2.x
for ne in new_elements:
  a_list.extend(ne)

答案 1 :(得分:1)

如果您想扩展列表,但只在原始列表上循环,则可以循环复制而不是原始列表:

for item in a_list[:]:
     a_list.extend(fun(item))

答案 2 :(得分:1)

你有没有尝试过列表推导?这可以通过在内存中创建单独的列表,然后在理解完成后将其分配到原始列表来实现。基本上它与第二个示例相同,但它不是导入展平函数,而是通过堆叠列表推导来展平它。 [编辑Matthias:将+更改为+ =]

a_list += [x for lst in [fun(item) for item in a_list] for x in lst]  

编辑:解释发生了什么。

所以首先要发生的是这部分在上面的代码中间:

[fun(item) for item in a_list]

这会将fun应用于item中的每个a_list,并将其添加到新列表中。问题是,因为fun(item)返回一个列表,现在我们有一个列表列表。所以我们运行第二个(堆叠的)列表理解来遍历我们刚刚在原始理解中创建的新列表中的所有列表:

for lst in [fun(item) for item in a_list]

这将允许我们按顺序遍历所有列表。那么:

[x for lst in [fun(item) for item in a_list] for x in lst]

这意味着每个x(我们在原始理解中创建的所有列表)中的每个lst(即每个项目),并将其添加到新列表中。

希望这更清楚。如果没有,我总是愿意进一步阐述。

答案 3 :(得分:0)

使用发电机

original_list = [1, 2]
original_list.extend((x for x in original_list[:]))

# [1, 2, 1, 2]
相关问题