我希望在循环时扩展一个列表:
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'表示),每个边界节点可以添加几个新的节点。
答案 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]