python - 这在 python : flat_array = sum( array_2d , [ ] 中如何工作)

标签 python arrays list multidimensional-array

要在 python 中将二维数组转换为一维数组,我在 leetcode 上找到了这个方法。但是找不到 它是如何一步一步逻辑地工作的?请解释。 也有人在 leetcode 上说: “当数组大小变得非常大时,这可能是二次运行时复杂度”

这是真的吗?如果是,怎么做?

a = [[4,2,5],[1,8,2],[7,5,6]]
flat  = sum(a,[])
flat

输出:[4, 2, 5, 1, 8, 2, 7, 5, 6]

最佳答案

sum 是如何工作的?

在 Python 中,列表可以用运算符 + 连接:

>>> [1] + [2, 3]
[1, 2, 3]

Python 中的sum 函数类似于:

>>> def my_sum(iterable, start=0):
...     for v in iterable:
...         start = start + v
...     return start
...

所以对于sum(a, []),可以理解如下操作:

>>> [] + [4, 2, 5] + [1, 8, 2] + [7, 5, 6]
[4, 2, 5, 1, 8, 2, 7, 5, 6]

但这不是一个好的做法,因为每次连接都会产生一个新列表,而不是在其中一个列表上进行连接:

>>> a = [1]
>>> b = [2, 3]
>>> c = a + b
>>> a, b, c
([1], [2, 3], [1, 2, 3])

这意味着每次连接需要 O(n + m) 时间(n 和 m 分别是两个列表的长度),而不是 O(m) .对于长度为 n 的 m 个列表,第一次长度为 n 的列表将与另一个长度为 n 的列表连接,下一次长度为 2n 的列表将与长度为 n 的列表连接...最后,花费的总时间将是:

(n + n) + (2n + n) + ... + (mn + n) = (m^2 + 3m) * n / 2 = O(m^2 * n)

更好的做法

简单的方法就是每次都使用in place concatenate:

def concatenate(lists):
    result = []
    for lst in lists:
        result += lst
    return result

更简洁的方法是使用functools.reduceoperator.iconcat :

>>> from functools import reduce
>>> from operator import iconcat
>>> reduce(iconcat, a, [])
[4, 2, 5, 1, 8, 2, 7, 5, 6]

您还可以使用 itertools.chain.from_iterable链接这些列表,然后使用 list构建:

>>> from itertools import chain
>>> list(chain.from_iterable(a))
[4, 2, 5, 1, 8, 2, 7, 5, 6]

或者使用嵌套列表comprehension :

>>> [val for lst in a for val in lst]
[4, 2, 5, 1, 8, 2, 7, 5, 6]

性能对比请引用:How do I make a flat list out of a list of lists?

关于python - 这在 python : flat_array = sum( array_2d , [ ] 中如何工作),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73095515/

相关文章:

C 动态内存与堆栈内存变量

c++ - 具有操作数据重置功能的字符数组

不继承属性的Python子类

Python 函数装饰器应该打印完整的方法名称

Python 多处理 - 只是不明白

python - 在 Python 中更改列表

python:对具有相同第一个元素的元组的元素进行分组

python - 为什么我在使用 Erlang 19.1.1 的 .Net Client 到 RabbitMQ 时出现 SSL 握手失败,但在 17.4、18.1 和 18.2 中却没有?

java - 创建泛型数组的两种方法

java - 从子数组创建列表而不在java中复制