【问题标题】:How to flatten a list to return a new list with all the elements?如何展平列表以返回包含所有元素的新列表?
【发布时间】:2014-06-17 22:09:54
【问题描述】:

我正在尝试编写一个名为 flatten_list 的函数,该函数将一个可能嵌套的列表作为输入,并返回一个包含输入列表的所有元素的非嵌套列表。

我的代码:

def flatten_list(alist):
    """
    >>> flatten_list([1,2,3])
    [1, 2, 3]
    >>> flatten_list([1, [2,3], [4, 5], 6])
    [1, 2, 3, 4, 5, 6]
    """
    flat_list = []
    for element in alist:
        flat_list += element
    return flat_list

此代码适用于包含字符串的列表,但不适用于整数值。如何更改代码以使其适用于两者?

谢谢

【问题讨论】:

    标签: python python-2.7


    【解决方案1】:

    一般来说,这会递归完成,例如:

    def flatten(input_, output=None):
        if output is None:
            output = []
        if isinstance(input_, basestring):
            output.append(input_)
        else:
            for item in input_:
                try:
                    flatten(item, output)
                except TypeError:
                    output.append(item)
        return output
    

    这适用于可迭代容器(例如setlisttupledict(仅限键))和内容(例如intfloatstr)的任意组合,使用常见的EAFP Python 样式。请注意字符串的特定例外,您可能不希望将其解包!

    几个使用示例:

    >>> flatten([1, [2, [3, [4, 5], 6], 7], 8])
    [1, 2, 3, 4, 5, 6, 7, 8]
    >>> flatten([1, "foo", ["bar", 2], 3])
    [1, 'foo', 'bar', 2, 3]
    >>> flatten([1, (2, 3), {4: 5}])
    [1, 2, 3, 4]
    >>> flatten("hello")
    ['hello']
    

    以及将不可迭代对象作为直接参数会发生什么:

    >>> flatten(1)
    
    Traceback (most recent call last):
      File "<pyshell#3>", line 1, in <module>
        flatten(1)
      File "<pyshell#1>", line 4, in flatten
        for item in input_:
    TypeError: 'int' object is not iterable
    

    【讨论】:

      【解决方案2】:

      你可以这样做:

      a = [1, [2,3], [4, 5], 6]
      
      def flatten(l,result = []):
          if isinstance(l, list):
              for i in l:
                  flatten(i)
          else:
              result.append(l)
          return result
      
      >>> print flatten(a)
      [1, 2, 3, 4, 5, 6]
      

      这将适用于更深的嵌套级别:

      >>> print flatten([1, [2, [3, 4]]])
      [1, 2, 3, 4]
      

      Demo

      【讨论】:

      • 首先,type(l) == int 应该是isinstance(l, int),它可以更好地处理继承。其次,在最终输出为 int 时才有效。
      • @jonrsharpe,谢谢。我已经更新了我的答案。现在效果更好了。
      【解决方案3】:

      使用集合。可迭代

      from collections import Iterable
      def flatten(items):
          for elem in items:
              if isinstance(elem,Iterable) and not isinstance(elem,str):
                  for sub_elem in flatten(elem):
                      yield sub_elem
              else:
                  yield elem
      
      
      
      
       In [15]:   print list(flatten((1, (2,3), [4, 5],{10,11,12}, 6)))
       [1, 2, 3, 4, 5, 10, 11, 12, 6]
      
      
       In [16]: print list(flatten((1, (2,3), (4,5,6), 6)))
       [1, 2, 3, 4, 5, 6, 6]
      
       In [17]: print list(flatten([1, "foo", ["bar", 2], 3]))
       [1, 'foo', 'bar', 2, 3]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-10-14
        • 1970-01-01
        • 1970-01-01
        • 2018-10-08
        • 1970-01-01
        • 2016-06-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多