嵌套列表的Python内置和

2024-04-27 02:42:20 发布

您现在位置:Python中文网/ 问答频道 /正文

当我完成leetcode1313时,我发现内置sum函数有一个特殊用法

Leetcode问题1313

我们得到了一个nums整数列表,表示用游程编码压缩的列表

考虑元素的每一对相邻元素{{CD3}}。对于每一对,在解压缩列表中有{{CD4}}元素,值为{{CD5>}。

返回已解压缩的列表

例1:

Input: nums = [1,2,3,4]
Output: [2,4,4,4]
Explanation: The first pair [1,2] means we have freq = 1 and val = 2 so we generate the array [2].
The second pair [3,4] means we have freq = 3 and val = 4 so we generate [4,4,4].
At the end the concatenation [2] + [4,4,4,4] is [2,4,4,4].

有一个使用sum的解决方案

nums = [1,2,3,4]
g = ([b] * a for a, b in zip(nums[::2], nums[1::2]))
print(list(g))
g = ([b] * a for a, b in zip(nums[::2], nums[1::2]))
print(sum(g,[]))

输出:

[[2], [4, 4, 4]]
[2, 4, 4, 4]

我的问题

我不知道为什么在这种情况下sum可以处理嵌套列表。有人能告诉我这件事吗?或者像这样的其他函数行为

下面是内置sumofficial guide


Tags: andthe函数元素列表haveval内置
2条回答

简短回答

给定的代码片段运行连续的列表连接

工作原理

大致上,内置的sum()函数是这样工作的:

def sum(iterable, /, start=0):
    total = start
    for x in iterable:
        total = total + x
    return total

+运算符调用左侧操作数上的__add__,以便3 + 4作为(3).__add__(4)运行,这是一种对整数的加法运算。同样地,[10, 20] + [30, 40, 50]作为[10, 20].__add__([30, 40, 50])运行,这是列表上的连接操作

下面是在给定示例中的结果:

>>> nums = [1,2,3,4]
>>> g = ([b] * a for a, b in zip(nums[::2], nums[1::2]))
>>> result = []
>>> x = next(g)
>>> result = result + x
>>> result
[2]
>>> x = next(g)
>>> result = result + x
>>> result
[2, 4, 4, 4]

为什么这不是一个好主意

连续的列表串联在每次加法后生成下一个列表,因此它们以^{}的速度运行,这意味着这是一个二次算法,在给定大输入时运行速度非常慢

更好的方法

不必在每一步都建立新的列表,只需extend将基本列表放置到位。它以^{}线性速度运行:

>>> nums = [1,2,3,4]
>>> g = ([b] * a for a, b in zip(nums[::2], nums[1::2]))
>>> result = []                 # new list
>>> for x in g:
        result.extend(x)        # extend in-place

>>> result
[2, 4, 4, 4]

更好的方法

{a5}提供了{a6}。这使得问题的解决变得简单:

>>> nums = [1,2,3,4]
>>> g = ([b] * a for a, b in zip(nums[::2], nums[1::2]))
>>> list(chain.from_iterable(g))
[2, 4, 4, 4]

该解决方案短,速度快,即使输入量大,也能很好地工作

sum(foo)只是使用+的定义作为初始值。默认情况下,初始值为0,因此对于列表sum(g)将失败,因为没有定义添加列表和int。通过传递一个显式的初始值[],这将强制sum(foo, [])等于foo[0] + foo[1] + ... + foo[n-1] + [],正如所观察到的那样

>>> sum([[1], [2]])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'list'
>>> sum([[1], [2]], [])
[1, 2]

此定义的例外情况是,即使将""指定为初始值,也不能将sumstr值列表一起使用。这是一个硬编码的异常,导致TypeError,并建议使用str.join

>>> sum(["foo", "bar"])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> sum(["foo", "bar"], "")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sum() can't sum strings [use ''.join(seq) instead]

相关问题 更多 >