用Python求和非整数([[1],[2]])= [1,2]

时间:2010-07-23 04:16:44

标签: python sum

是否可以在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__),但是有更优雅的方法吗?

7 个答案:

答案 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)