将 args 转换为扁平列表?

3 投票
4 回答
2600 浏览
提问于 2025-04-15 20:58

我知道这个问题和其他几个问题很相似,但是我就是无法让这个函数正常工作。

def flatten(*args):
    return list(item for iterable in args for item in iterable)

我想要的输出结果是:

flatten(1) -> [1]
flatten(1,[2]) -> [1, 2]
flatten([1,[2]]) -> [1, 2]

我现在用的这个函数是从另一个StackOverflow的回答里拿来的,但它似乎根本不能产生正确的结果:

>>> flatten([1,[2]])
[1, [2]]

4 个回答

1

检查__iter__是否存在在扁平化字典时可能会有点奇怪:

>>> def flatten(*args):
...     output = []
...     for arg in args:
...         if hasattr(arg, '__iter__'):
...             output.extend(flatten(*arg))
...         else:
...             output.append(arg)
...     return output
...
>>> adict = {1:2, 3:4, 5:6}
>>> blist = ['a', 'b', 'c']
>>> raw = [adict, blist]
>>> flatten(raw)
[1, 3, 5, 'a', 'b', 'c']

我觉得扁平化应该只适用于列表和元组:

import types

def flatten(*args):
    output = []
    for arg in args:
        if isinstance(arg, (types.ListType, types.TupleType)):
            output.extend(flatten(*list(arg)))
        else:
            output.append(arg)
    return output

adict = {1:2, 3:4, 5:6}
blist = ['a', 'b', 'c']
raw = [adict, blist]
print flatten(raw)
4

如果你想把任意层级嵌套的列表变成一个平坦的列表,你需要一个递归函数:

def flatten(ls):
  if isinstance(ls, list):
     return [fa for a in ls for fa in flatten(a)]
  else:
     return [ls]

(如果你要处理很大的结构,可以用生成器来提高效率,而不是直接返回列表。)

这个函数也可以被重新利用,来创建一个可以接受多个参数的函数:

def pflatten(*ls):
   return flatten(list(ls))
6

要快速解决这个问题,你只需要把你的第二个函数改成递归的形式。

def flatten(*args):
    output = []
    for arg in args:
        if hasattr(arg, '__iter__'):
            output.extend(flatten(*arg))
        else:
            output.append(arg)
    return output

撰写回答