扩展列表中的元素

3 投票
3 回答
5773 浏览
提问于 2025-04-15 18:47

我在寻找一种“好”的方法来处理一个列表,其中一些元素需要扩展成更多的元素(只扩展一次,结果不再扩展)。

标准的迭代方法是这样做:

i=0
while i < len(l):
   if needs_expanding(l[i]):
      new_is = expand(l[i])
      l[i:i] = new_is
      i += len(new_is)
   else:
      i += 1

但这样看起来挺麻烦的。我可以用下面的方式把内容写入一个新列表:

nl = []
for x in l:
   if needs_expanding(x):
      nl += expand(x)
   else:
      nl.append(x)

不过这两种方法似乎都太长了。或者我可以简单地进行两次遍历,然后再把列表压平:

flatten(expand(x) if needs_expanding(x) else x for x in l)
# or
def try_expanding(x)....
flatten(try_expanding(x) for x in l)

但这样也感觉不太“对”。

有没有其他更清晰的方法来做到这一点呢?

3 个回答

2

最后一种方法可能是最符合Python风格的,但你也可以试试用隐式循环(在Python 3中叫生成器)配合map函数来实现:

flatten(map(lambda x: expand(x) if needs_expanding(x) else x, l))
flatten(map(try_expanding, l))
3

你之前的两个回答就是我会采取的做法。不过我对 flatten() 这个函数不太熟悉,但如果你有这样的函数,那听起来很不错。你也可以使用内置的 sum() 函数:

sum(expand(x) if needs_expanding(x) else [x] for x in l, [])
sum(needs_expanding(x) and expand(x) or [x] for x in l, [])
2

如果你生成的列表不需要随机访问的话,你也可以写一个生成器。

def iter_new_list(old_list):    
    for x in old_list:
       if needs_expanding(x):
           for y in expand(x):
               yield y
       else:
           yield x

new_list = list(iter_new_list(old_list))

这个方法在功能上和你的第二个例子是一样的,但在实际应用中可能会更容易理解。

另外,Python的编码标准不允许使用小写字母l作为变量名,因为它和数字1几乎看不出区别。

撰写回答