是否可以在python中获取非整数的总和?
命令
sum([[1],[2]])
例如,给出错误
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'
我怀疑sum会尝试将0添加到列表[1],导致失败。我确信有很多黑客可以解决这个限制(在一个类中包装东西,并手动实现__radd__
),但是有更优雅的方法吗?
答案 0 :(得分:9)
看起来你想要这个:
>>> sum([[1],[2]], [])
[1, 2]
你是对的,它试图将0添加到[1]并收到错误。解决方案是给sum
一个额外的参数给出起始值,对于你来说这将是空列表。
编辑:正如gnibbler所说,sum
不是连接事物的好方法。如果您只想汇总一系列事情,则应该使用reduce
而不是仅使用__radd__
创建自己的sum
函数。这是一个例子(与sum
具有相同的不良行为):
>>> reduce(lambda x, y: x+y, [[1],[2]])
[1, 2]
答案 1 :(得分:8)
在数字以外的任何地方使用sum()
是个坏主意,因为它具有序列/字符串/等的四元性能。
最好使用列表理解来汇总列表
[j for i in [[1],[2]] for j in i]
答案 2 :(得分:5)
使用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, ...]
就个人而言,我更喜欢这个而不是列表理解,因为很难记住哪个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))
当外部列表大小非常短时,它显示sum
只有效率 。但是你有一个更有效的变体:m[0]+m[1]
。
答案 3 :(得分:3)
正如the docs所说,
可迭代的项目通常是 数字,不允许 字符串。
这意味着实际禁止除了数字之外的任何事情的繁琐过程(除了禁止汇总字符串,特别令人发指和常见的错误)都被避开了 - 如果你总结任何但是数字你可能会破坏程序的性能,但是,嘿,Python并不是要阻止程序员做出每一个那种可怕的错误。
如果你坚持以错误的方式做事,正如其他答案所提到的那样,使用sum
的第三个参数(作为起始值,而不是默认值0
)是正确的做错事的方法;-)。所以,你的问题的字面答案:
是否有可能取得总和 python中的非整数?
(一旦删除了非常错误的建议,整数的行为与此处任何其他类型的数字有任何不同,通过将其改为“非数字” - 总结任何类型的数字是相当的罚款,并不一定需要任何特殊的预防措施,但math.fsum更适合汇总float
s)是......:“是的, 可能(就像它的一样)可能会用锤子敲打你的拇指非常痛苦) - 请注意,它绝对不是可取的(就像锤击你的拇指一样),但是,肯定是 可能,如果你真的坚持“; - )。
答案 4 :(得分:1)
我很少误解你的问题是为了补充并提出这个解决方案:
# for me the guestion looks for me to do sum of sum of list
# i would do like this
list_of_numlists=[[1,2,3],[2,3,4]]
print "Input =",list_of_numlists
sum_of_it=sum(sum(x) for x in list_of_numlists)
print "Sum = %i" % sum_of_it
## --> Sum = 15
# second version to understand the request is
sum_of_items=[sum(x) for x in zip(*list_of_numlists)]
print "Sum of each is", sum_of_items
""" Output:
Input = [[1, 2, 3], [2, 3, 4]]
Sum = 15
Sum of each is [3, 5, 7]
"
“”
实际上你不应该谈论总和而是连接或加入序列。
答案 5 :(得分:0)
sum(iterable [,start]) Sums从左到右开始和可迭代的项目并返回总数。 start默认为0. iterable的项通常是数字,不允许是字符串。 在[26]中:sum([[1],[2]],[]) 出[26]:[1,2]
与文件一样......
顺便说一下,Gabe给出了使用reduce的正确解决方案(lambda x,y:x + y,[[1],[2]])。 或者,您可以使用非专业人员方法: -
在[69]中:l = [[1],[2]]
在[70]中:a = str(l [0])。strip('[]')
在[71]中:b = str(l [1])。strip('[]')
在[72]中:l = [int(a),int(b)]
在[73]中:l 出[73]:[1,2]
答案 6 :(得分:0)
对于一个元素序列的情况,还有特殊的解决方案:
m = [[i] for i in range(200)]
list_of_m = list((zip(*m))[0])
print list_of_m
此外,如果列表中有字符串,则可以使用标准Python连接来连接
''.join(m)