Sum une liste qui contient 'None' en utilisant Python

fondamentalement, ma question Est de dire que vous avez une liste contenant 'aucun' comment essaieriez-vous de récupérer la somme de la liste. Voici un exemple que j'ai essayé qui ne fonctionne pas et je reçois l'erreur:TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'. Merci

def sumImport(self):
    my_list = [[1,2,3,None],[1,2,3],[1,1],[1,1,2,2]]
    k = sum(chain.from_iterable(my_list))
    return k
24
demandé sur alecxe 2012-09-01 21:33:00

6 réponses

Vous pouvez utiliser filter function

>>> sum(filter(None, [1,2,3,None]))
6

mise à Jour à partir des commentaires

typiquement filter utilisation filter(func, iterable), mais le passage None comme premier argument est un cas spécial, décrit dans Python docs. Le cite:

si la fonction est None, la fonction d'identité est supposée, c'est-à-dire que tous les éléments itérables qui sont faux sont supprimés.

28
répondu Alexey Kachayev 2012-09-01 17:40:40

Supprimer None (et zéro) éléments avant de sommation à l'aide de filter:

>>> k = sum(filter(None, chain.from_iterable(my_list)))
>>> k
20

voir pourquoi cela fonctionne, voir le documentation pour filter:

filter(function, iterable)

construisez une liste à partir des éléments de iterable pour function renvoie la valeur true. iterable peut être soit une séquence, un récipient qui supporte l'itération, ou un itérateur. Si iterable est une chaîne ou un tuple, le résultat a aussi ce type; sinon c'est toujours une liste. Si la fonction est None, la fonction d'identité est supposée, c'est-à-dire que tous les éléments itérables qui sont faux sont supprimés.

Notez que filter(function, iterable) est équivalent à [item for item in iterable if function(item)] si la fonction n'est pas None et [item for item in iterable if item] si la fonction est None.

8
répondu Mark Byers 2012-09-01 17:41:09

une autre suggestion:

from itertools import chain
k = sum(x for x in chain.from_iterable(my_list) if x)
5
répondu Tim Pietzcker 2015-10-25 12:28:53

en Supposant que vous souhaitez traiter None en tant que zéro, un moyen simple est

sum(x if x is not None else 0 for x in chain.from_iterable(my_list))
4
répondu BrenBarn 2012-09-01 17:34:34

vous avez toujours l'option d'écrire simplement la boucle que vous voulez:

k = 0
for sublist in my_list:
    for val in sublist:
        if val is not None:
            k += val

mais ça ne fait certainement pas de mal de savoir à propos de filter soit.

0
répondu Jason Orendorff 2012-09-01 17:41:07

explicitement, cela équivaut à filtrer:

k = sum([x for x in chain.from_iterable(my_list) if x])

cela m'évite de me souvenir d'une autre fonction. :P

0
répondu Taro Sato 2012-09-01 18:23:01