【问题标题】:Flatten multi dimensional array in python 3在python 3中展平多维数组
【发布时间】:2018-05-06 01:40:31
【问题描述】:

我有一个数字列表:testList = [1, [1], [12], 2, 3]

我希望它变成:flatList = [1, 1, 12, 2, 3]

使用如下所示的典型列表理解是行不通的。

flatList = [val for sublist in testList for val in sublist]
TypeError: 'int' object is not iterable

我怀疑这是因为未嵌套的项目被视为可迭代的子列表,所以我尝试了这个:

flatList = [val if isinstance(sublist, int) == False else val for sublist in testlist for val in sublist]

但我不清楚语法,或者是否有更好的方法来做到这一点。试图从 else 子句中删除 val 意味着 val 未定义。照原样,它仍然给我同样的 TypeError。

下面的代码确实对我有用,但我很想看看它是否可以以列表理解的方式完成,以及人们对此的看法。

for sublist in testlist:
    if type(sublist) == int:
        flat.append(sublist)
    else:
        for val in sublist:
            flat.append(val)
print(flat)

>>>[1, 1, 12, 2, 3]

【问题讨论】:

  • 子列表可以包含多个整数吗?
  • 在 else 块中,可以将 for 替换为 flat.extend(sublist)
  • @AidanHorton 它可以包含多个整数。
  • @stack_n_queue 感谢您指出这一点。

标签: python python-3.x multidimensional-array


【解决方案1】:

由于您使用的是 Python 3,因此您可以通过递归函数利用 yield from。它已在 Python 3.3 中引入。

作为奖励,您可以展平任意嵌套列表、元组、集合或范围:

test_list = [1, [1], [12, 'test', set([3, 4, 5])], 2, 3, ('hello', 'world'), [range(3)]]

def flatten(something):
    if isinstance(something, (list, tuple, set, range)):
        for sub in something:
            yield from flatten(sub)
    else:
        yield something


print(list(flatten(test_list)))
# [1, 1, 12, 'test', 3, 4, 5, 2, 3, 'hello', 'world', 0, 1, 2]
print(list(flatten('Not a list')))
# ['Not a list']
print(list(flatten(range(10))))
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

这是另一个带有调试行的示例:

def flatten(something, level=0):
    print("%sCalling flatten with %r" % ('  ' * level, something))
    if isinstance(something, (list, tuple, set, range)):
        for sub in something:
            yield from flatten(sub, level+1)
    else:
        yield something

list(flatten([1, [2, 3], 4]))
#Calling flatten with [1, [2, 3], 4]
#  Calling flatten with 1
#  Calling flatten with [2, 3]
#    Calling flatten with 2
#    Calling flatten with 3
#  Calling flatten with 4

【讨论】:

  • 我会改名为 something iterable
  • 好吧,这取决于你,但如果 something 不是可迭代的,我会提出 TypeError(因为在整数和字符串上调用 flatten 没有意义?)跨度>
  • 好的,我现在明白了。我经常难以理解递归:)
  • 哇,非常有用。不是我熟悉的函数,很高兴看到 isinstance() 如何与多种类型一起使用。
【解决方案2】:

如果子列表总是只包含一项,那么

flatList = [item[0] if isinstance(item, list) else item for item in testList]

【讨论】:

  • 谢谢,在这些情况下很有用。
猜你喜欢
  • 2012-08-27
  • 2020-06-06
  • 1970-01-01
  • 2011-11-14
  • 1970-01-01
  • 2011-09-05
  • 2010-11-22
  • 1970-01-01
相关资源
最近更新 更多