2010-07-23 57 views
2

python中可以取非整數嗎?在Python中求和非整數sum([[1],[2]])= [1,2]

命令

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' 

我懷疑總和嘗試添加0到列表[1],從而產生故障。我確信有很多黑客可以解決這個限制(在課堂中包裝東西,並手動實施__radd__),但是有沒有更好的方法可以做到這一點?

回答

8

它看起來像你想的:

>>> sum([[1],[2]], []) 
[1, 2] 

你是正確的,它試圖加0 [1],並得到一個錯誤。解決辦法是給sum一個額外的參數給出起始值,這對你來說應該是空的列表。

編輯:正如gnibbler說的,雖然,sum不是連接事情的好方法。如果你只是想聚合一系列的東西,你應該使用reduce而不是自己的__radd__函數只使用sum。下面是一個例子(具有相同的可憐行爲sum):

>>> reduce(lambda x, y: x+y, [[1],[2]]) 
[1, 2] 
7

這是一個壞主意,在數字之外的其他任何使用sum(),因爲它具有序列/串/等二次型性能。

更好地使用列表理解來總結你的列表

[j for i in [[1],[2]] for j in i] 
+0

+1不是答案他一直在尋找,但這是一個有價值的建議。對於鏈表來說,它可以在性能方面表現出色,但在Python中很少見。 – delnan 2010-07-23 04:41:17

+1

@delnan爲什麼在Python列表中這不會表現明智? – 2010-07-23 07:41:21

+0

@Xavier:Python的'list'不是一個鏈表。 – kennytm 2010-07-23 10:40:34

3

由於the docs說,

可迭代的項目通常 號碼,不得將 字符串。

這意思是,實際上禁止任何東西,但數量(除禁止總結字符串,特別令人髮指的常見錯誤)的繁瑣過程,迴避 - 如果你總結什麼號碼,如果沒有好的目的,可能會破壞你的程序的性能,但是,嘿,Python並不是真的在阻止程序員做出每一種可怕的錯誤。

如果您確實堅持以錯誤的方式做事,如其他答案所述,則使用sum的第三個參數(作爲起始值而不是默認值0)是做錯事的正確方法; - )。所以,你的問題的字面上的答案:

是否有可能採取總和 python非整數?

(一旦非常錯誤的建議被刪除,該整數任何行爲不同於任何其他種類的數量在這裏的,被改寫爲「非數字」 - 總結任何的種類數字是相當精細,並且不一定需要任何特別的預防措施,儘管math.fsum更適合用於求和float s)是......:「是的,它可能的(就像可以用錘子敲擊你的拇指相當痛苦一樣) - 頭腦你,這絕對不是建議(就像錘擊你的拇指不是),但它,它是絕對可能,如果你真的堅持「;-)。

0

sum(iterable [,start]) 將start和iterable的項目從左到右彙總並返回總數。開始默認爲0. iterable的項目通常是數字,不允許是字符串。 在[26]:合計([[1],[2]],[]) 輸出[26]:[1,2]

如在文檔...

順便說Gabe給出了使用reduce的正確解決方案(lambda x,y:x + y,[[1],[2]])。 備選地可以使用捻人方法: -

在[69]:L = [[1],[2]]

在[70]爲:a = STR(L [0])。條帶( '[]')

在[71]:b = STR(L [1])條( '[]')

在[72]:L = [INT(a)中, INT(b)]

在[73]:升 缺貨[73]:[1,2]

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

連接使用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, ...] 

就個人而言,我更喜歡這種過度列表理解,因爲它是很難記住這對於循環至上。甚至還有一個更有效的變體,list(chain.from_iterable(m))

微基準結果(使用timeit模塊的Python 3 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]

+1

當然,您還記得首先使它工作,然後優化熱點。自然和簡單的表達更重要(應優先考慮代碼的可讀性)。對我來說[j for i in m for j in i] 是自我記錄代碼。 – 2010-07-23 10:30:15

+0

@Tony:恩,對我來說'[我爲我在m中爲j我']是[兩級列表理解](http://google-styleguide.googlecode.com/svn/trunk/pyguide.html #List_Comprehensions)。 – kennytm 2010-07-23 10:39:47

0

對於一個元素序列的情況下,也有特殊的解決方案:

m = [[i] for i in range(200)] 
list_of_m = list((zip(*m))[0]) 
print list_of_m 

此外,如果你有一個字符串列表,你可以使用標準的Python加盟鏈狀

''.join(m) 
相關問題