是否可以在python中获取非整数的总和?
命令
sum([[1],[2]])
Run Code Online (Sandbox Code Playgroud)
例如,给出错误
Traceback (most recent call last):
File "<pyshell#28>", line 1, in <module>
sum([[1,2,3],[2,3,4]])
TypeError: unsupported operand type(s) for +: 'int' and 'list'
Run Code Online (Sandbox Code Playgroud)
我怀疑sum会尝试将0添加到列表[1],导致失败.我确信有很多黑客可以解决这个限制(在一个类中包装东西,并__radd__手动实现),但有更优雅的方法来做到这一点吗?
看起来你想要这个:
>>> sum([[1],[2]], [])
[1, 2]
Run Code Online (Sandbox Code Playgroud)
你是对的,它试图将0添加到[1]并收到错误.解决方案是给出sum一个额外的参数给出起始值,对于你来说这将是空列表.
编辑:正如gnibbler所说,sum并不是连接事物的好方法.如果你只想聚合一系列事物,你应该使用reduce而不是__radd__仅仅使用自己的功能sum.这是一个例子(具有相同的不良行为sum):
>>> reduce(lambda x, y: x+y, [[1],[2]])
[1, 2]
Run Code Online (Sandbox Code Playgroud)
使用sum()除数字之外的任何东西都是一个坏主意,因为它具有序列/字符串/等的四元性能.
最好使用列表理解来汇总列表
[j for i in [[1],[2]] for j in i]
Run Code Online (Sandbox Code Playgroud)
连接使用更有效itertools.chain.
>>> m = [[i] for i in range(200)]
>>> m
[[0], [1], [2], [3], [4], [5], [6], [7], [8], ...]
>>> from itertools import *
>>> list(chain(*m))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, ...]
Run Code Online (Sandbox Code Playgroud)
就个人而言,我更喜欢这个而不是列表理解,因为很难记住哪个for循环首先出现.甚至还有一种更有效的变种list(chain.from_iterable(m)).
Microbenchmark结果(Python 3使用timeit模块.列表大小为p x q表示m = [list(range(q)) for _ in range(p)]):
list size | chain(*m) | sum(m,[]) | list comp | flatten |
----------+------------+---------------+------------+------------+
2 x 1 | 1.78 µs | 0.646 µs | 0.905 µs | 1.49 µs |
20 x 1 | 4.37 µs | 7.49 µs | 5.19 µs | 3.59 µs |
200 x 1 | 26.9 µs | 134 µs | 40 µs | 24.4 µs |
2000 x 1 | 233 µs | 12.2 ms | 360 µs | 203 µs |
----------+------------+---------------+------------+------------+
2 x 1 | 1.78 µs | 0.646 µs | 0.905 µs | 1.49 µs |
2 x 10 | 2.55 µs | 0.899 µs | 3.14 µs | 2.2 µs |
2 x 100 | 9.07 µs | 2.03 µs | 17.2 µs | 8.55 µs |
2 x 1000 | 51.3 µs | 21.9 µs | 139 µs | 49.5 µs |
----------+------------+---------------+------------+------------+
chain(*m) -> list(chain(*m))
sum(m,[]) -> sum(m, [])
list comp -> [j for i in m for j in i]
flatten -> icfi = chain.from_iterable; list(icfi(m))
Run Code Online (Sandbox Code Playgroud)
它表明只有在外部列表大小很短时才sum有效.但是你有一个更有效的变体:.m[0]+m[1]