2010-09-23 6 views
10

Existe-t-il une manière plus idiomatique d'additionner des longueurs de chaîne en Python qu'en utilisant une boucle?Python: Somme des longueurs de chaîne

length = 0 
for string in strings: 
    length += len(string) 

J'ai essayé sum(), mais il ne fonctionne que pour les entiers:

>>> sum('abc', 'de') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: sum() can't sum strings [use ''.join(seq) instead] 
+1

Qu'entendez-vous par "plus rapide"? Moins de frappe ou une exécution plus rapide? –

+0

@Richard: Désolé, je pensais "plus vite" comme en tapant moins, mais ce que je veux dire en réalité est idiomatique. – Zaz

+1

Pas de soucis. Je pense que c'est ce que tout le monde pensait. Je ne suis qu'un pédant! –

Répondre

2

Je sais que c'est une vieille question, mais je ne peux pas m'empêcher de noter que le message d'erreur Python dit comment faire ceci:

TypeError: sum() can't sum strings [use ''.join(seq) instead] 

Alors:

>>> strings = ['abc', 'de'] 
>>> print len(''.join(strings)) 
5 
+0

Il semble inutile de concaténer les cordes quand vous n'avez pas à le faire, mais +1 pour ajouter une autre façon de résoudre le problème! – Zaz

+0

Je ne sais pas - j'ai depuis longtemps cessé de me demander si le code était inutile pour les systèmes non temps réel. Mais puisque vous avez mentionné "moins de frappe", cela semble assez serré. – Auspex

+1

@Zaz Gaspillage?C'est de loin la plus rapide des trois solutions, si l'on en croit le module 'timeit'. La réponse que vous avez acceptée, 'sum (len (s) pour s dans les chaînes)', est plus de trois fois plus lente, et est presque deux fois plus lente que 'sum (map (len, strings))'. (La vitesse, bien sûr, n'a pas beaucoup d'importance en Python - si vous vouliez utiliser la vitesse, vous utiliseriez Pypy, comme le dit le dicton - mais l'expression génératrice complète est également un peu gênante pour IMO par rapport aux autres.) –

28
length = sum(len(s) for s in strings) 
+0

C'est certainement une manière plus idiomatique de l'exprimer mais je ne pense pas que ce soit plus efficace en termes de calcul. Encore, +1 pour l'élégance et la Pythonicité! –

+1

Si vous êtes vraiment inquiet au sujet de l'efficacité computationnelle, vous ne devriez probablement pas utiliser Python, ou écrire la partie intensive en C ou C++ (ou la bibliothèque de Weave de SciPy si vous êtes courageux). J'aime ce style parce qu'il est plus lisible pour les autres développeurs Python. –

+0

Merci, c'est beaucoup plus court et plus facile à comprendre que mon code. – Zaz

2
print(sum(len(mystr) for mystr in strings)) 
13

Ma première façon de le faire serait sum(map(len, strings)). Une autre manière consiste à utiliser une expression de liste ou une expression de générateur comme les autres réponses ont posté.

+0

Bonne réponse, mais j'ai accepté [la réponse de liori] (http://stackoverflow.com/questions/3780403#3780412) parce que je l'ai trouvé plus idiomatique. – Zaz

+0

@Josh: La plupart des gens trouveront en effet le genexp plus pythonique. Je voulais juste ajouter ceci pour être complet. – Daenyth

1

Voici une autre façon d'utiliser l'opérateur. Je ne sais pas si c'est plus facile à lire que la réponse acceptée.

import operator 

length = reduce(operator.add, map(len, strings)) 

print length 
-1

Juste pour ajouter à ...

numéros Ajout d'une liste stockée sous forme de chaîne

Nos = [ '1', '14', '34']

length = sum (int (s) pour s dans nos)

3

le plus court et le plus rapide est d'appliquer une functional programming style avec map() et sum():

>>> data = ['a', 'bc', 'def', 'ghij'] 
>>> sum(map(len, data)) 
10 

En Python 2, utilisez itertools.imap au lieu de carte pour une meilleure performances de la mémoire:

>>> from itertools import imap 
>>> data = ['a', 'bc', 'def', 'ghij'] 
>>> sum(imap(len, data)) 
10 
Questions connexes