代码之家  ›  专栏  ›  技术社区  ›  viraptor

展开列表中的元素

  •  3
  • viraptor  · 技术社区  · 14 年前

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

    标准的迭代方法是:

    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 回复  |  直到 14 年前
        1
  •  2
  •   ddaa    14 年前

    如果在生成的列表中不需要随机访问,也可以使用write a generator。

    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作为变量名,因为它与数字名称几乎没有区别。

        2
  •  3
  •   John Kugelman Michael Hodel    14 年前

    你最后的两个答案是我会做的。我不熟悉 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, [])
    
        3
  •  2
  •   Tor Valamo    14 年前

    最后一个可能是您最喜欢的pythonic,但是您可以尝试使用map:

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