2015-11-05 14 views
16

Quando voglio spiegare una lista, ho trovato un modo come di seguito:Cosa fa la somma della funzione integrata con sum (list, [])?

>>> a = [[1, 2], [3, 4], [5, 6]] 
>>> a 
[[1, 2], [3, 4], [5, 6]] 
>>> sum(a, []) 
[1, 2, 3, 4, 5, 6] 

Non so cosa sia successo in queste righe, e the documentation stati:

sum(iterable[, start])

Sums start and the items of an iterable from left to right and returns the total. start defaults to 0 . The iterable's items are normally numbers, and the start value is not allowed to be a string.

For some use cases, there are good alternatives to sum() . The preferred, fast way to concatenate a sequence of strings is by calling ''.join(sequence) . To add floating point values with extended precision, see math.fsum() . To concatenate a series of iterables, consider using itertools.chain() .

New in version 2.3.

Non è vero pensi che l'inizio dovrebbe essere un numero? Perché lo [] può essere scritto qui?

(sum(a, [])) 

risposta

22

Don't you think that start should be a number?

startè un numero, per default; 0, secondo la documentazione che hai citato. Quindi quando si fa ad es .:

sum((1, 2)) 

è valutato come 0 + 1 + 2 ed è uguale a 3 e tutti sono felici. Se si desidera iniziare da un numero diverso, è possibile fornire invece:

>>> sum((1, 2), 3) 
6 

Finora, tutto bene.


Tuttavia, ci sono altre cose che è possibile utilizzare + su, come le liste:

>>> ['foo'] + ['bar'] 
['foo', 'bar'] 

Se si tenta di utilizzare sum per questo, però, aspettandosi lo stesso risultato, si ottiene un TypeError:

>>> sum((['foo'], ['bar'])) 

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

perché ora sta facendo 0 + ['foo'] + ['bar'].

Per risolvere questo problema, è possibile fornire il proprio start come [], quindi diventa [] + ['foo'] + ['bar'] e tutto è di nuovo buono. Quindi, per rispondere:

Why [] can be written here?

perché anche se start default un numero, non è così hanno essere uno; altre cose possono essere aggiunte, e questo è utile per le cose esattamente come quello che stai facendo attualmente.

+1

'sum' è in realtà codificato per rifiutare le stringhe. Fornisce l'errore 'TypeError: sum() non può sommare le stringhe [usa '' .join (seq) invece ' – interjay

+0

@interjay sì, appena rilevato che durante la modifica dell'OP e risolto di conseguenza – jonrsharpe

+0

Buona risposta, imparato qualcosa di nuovo:) – Noxeus

5

realtà la funzione sum chiama l'attributo __add__ del start in ogni iterazione con tutti gli elementi di un iterabile.

Ad esempio:

>>> [].__add__([2,3]) 
[2, 3] 
#OR 
>>> [] + [1,2,3] 
[1, 2, 3] 

E in questo caso il risultato sarebbe una lista concatenata del vostro ingresso lists.Actually ad un punto di vista algoritmico che fa i seguenti processi:

>>> a = [[1, 2], [3, 4], [5, 6]] 
>>> start = [] 
>>> for i in a: 
...  start += i 
... 
>>> start 
[1, 2, 3, 4, 5, 6] 

Non che puoi chiamare la funzione sum su ogni sequenza di oggetti che hanno un attributo __add__.Ma si noti che poiché l'argomento predefinito è start è 0 se il tuo oggetto non era un numero intero ll alzo un TypeError. In questo caso è necessario specificare un valore corretto per la funzione start.

>>> class newObj(object): 
... def __init__(self,val): 
...   self.val = val 
... def __add__(self,item): 
...  return '{}_____{}'.format(self.val,item) 
... 
>>> 
>>> start=newObj('new_obj') 
>>> 
>>> start 
<__main__.newObj object at 0x7f75f9241c50> 
>>> 
>>> start + 5 
'new_obj_____5' 
>>> 
>>> 
>>> sum(['1','2','3'],start) 
'new_obj_____123' 
+0

Grazie, penso di averlo capito. :-) –

2

si somma il start con il contenuto del iterabile che fornisci come primo argomento. sum non limita lo type di start a un numero int per consentire vari casi di aggiunta.

Essenzialmente somma fa qualcosa di simile:

a = [[1, 2], [3, 4], [5, 6]] 
sum(a, number) 

traduce approssimativamente a:

number += every value in the list a 

Poiché ogni valore nella lista a è una lista funziona e la somma precedente, quando espanso, sguardi In questo modo:

number + [1, 2] + [3, 4] + [5, 6] 

Quindi se si immette un int ciò comporterà uno sfortunato TypeError perché l'aggiunta di int e list non è consentita.

1 + [1, 2] == I hope you like TypeErrors 

Tuttavia, se si immette un elenco [] è semplicemente andando a unire gli elementi di a insieme e il risultato in lista appiattita che conosciamo e amiamo.

Il valore di start predefinito è 0 un int principalmente perché il caso più comune di sommatoria è aritmetico.

+1

Grazie, penso di averlo capito. :-) –

Problemi correlati