web-dev-qa-db-fra.com

La manière la plus pythonique de concaténer des chaînes

Compte tenu de cette petite liste inoffensive:

>>> lst = ['o','s','s','a','m','a']

Mon objectif est de concaténer pythoniquement les petits démons en utilisant l'une des méthodes suivantes:

A. fonction de chaîne simple pour faire le travail, bref, pas d'importations

>>> ''.join(lst)
'ossama'

Lambda, lambda, lambda

>>> reduce(lambda x, y: x + y, lst)
'ossama'

C. mondialisation (ne rien faire, tout importer)

>>> import functools, operator
>>> functools.reduce(operator.add, lst)
'ossama'

Veuillez suggérer d'autres moyens Pythoniques pour accomplir cette tâche magnanime.

Veuillez classer (niveau Pythonic) et évaluer les solutions en donnant des explications concises.

Dans ce cas, la solution la plus Pythonique est-elle la meilleure solution de codage?

42
random guy

Jetez un oeil à Guido essai sur python optimisation, il couvre la conversion de listes de nombres en chaînes. À moins que vous n'ayez une bonne raison de faire autrement, utilisez l'exemple join.

35
Dana the Sane
''.join(lst)

la seule façon Pythonique:

  • clair (ce que font tous les grands garçons et ce qu'ils attendent de voir),
  • simple (aucune importation supplémentaire nécessaire, stable dans toutes les versions),
  • rapide (écrit en C) et
  • concis (sur une chaîne vide, joindre les éléments d'itérable!).
62
SilentGhost

Bien sûr, c'est join. Comment puis-je savoir? Faisons-le d'une manière vraiment stupide:
Si le problème n'ajoutait que 2 chaînes, vous utiliseriez très probablement str1 + str2. Que faut-il pour passer à un niveau supérieur? Instinctivement, pour la plupart (je pense), il faudra utiliser sum. Voyons comment ça se passe:

In [1]: example = ['a', 'b', 'c']
In [2]: sum(example, '')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython console> in <module>()
TypeError: sum() can't sum strings [use ''.join(seq) instead]

Hou la la! Python m'a simplement dit quoi utiliser! :)

18
abyx

Voici la manière la moins Pythonique:

out = ""
for x in range(len(lst)):
  for y in range(len(lst)):
    if x + y == len(lst)-1:
        out = lst[y] + out
7
Eli

J'utilise moi-même la méthode "join", mais à partir de python 2.6 il y a un type de base peu utilisé: bytearray.

Les bytearrays peuvent être incroyablement utiles - pour les chaînes contenant des textes, car la meilleure chose est d'avoir ensuite en unicode, la voie "join" est la voie à suivre - mais si vous traitez plutôt des données binaires, les bytearrays peuvent être à la fois plus Pythonique et plus efficace:

>>> lst = ['o','s','s','a','m','a']
>>> a = bytearray(lst)
>>> a
bytearray(b'ossama')
>>> print a
ossama

il s'agit d'un type de données intégré: aucune importation n'est nécessaire - il suffit de l'utiliser ensuite - et vous pouvez utiliser un tableau de bord n'est pas en tête de liste pour commencer - ils devraient donc être plus efficaces que la "jointure", car il n'y a pas de copie de données vers obtenir la représentation sous forme de chaîne d'un sous-tableau.

6
jsbueno

Grande réponse de SilenGhost MAIS, juste quelques mots sur la reduce "alternative" présentée

A moins que vous n'ayez une très très TRÈS bonne raison de concaténer des chaînes en utilisant + Ou operator.add (La plus fréquente , que vous avez peu de chaînes fixes), vous devez toujours utiliser join.

Tout simplement parce que + Génère une nouvelle chaîne qui est la concaténation de deux chaînes, sauf si la jointure ne génère qu'une seule chaîne finale. Imaginez donc que vous ayez 3 chaînes:

A + B + C
-->
D = A + B
final = D + C

D'accord, cela ne semble pas grand-chose, mais vous devez réserver de la mémoire pour D. De plus, en raison de python l'utilisation de chaînes, générer une nouvelle chaîne intermédiaire, c'est en quelque sorte cher ...

Maintenant, avec 5 cordes

A + B + C + D + E
-->
F = A + B
G = F + C
H = G + D
final = H + E

En supposant le meilleur scénario (si nous faisons (A + B) + (C + D) + E, nous finirons par avoir trois chaînes intermédiaires en même temps en mémoire), cela génère 3 chaînes intermédiaires ... Vous avez pour générer un nouvel objet python, réserver de l'espace mémoire, libérer la mémoire plusieurs fois ... Aussi la surcharge de l'appel d'une fonction Python (qui n'est pas petite)

Pensez-y maintenant avec 200 cordes. Nous finirons avec un grand nombre ridicule de chaînes intermédiaires, chacune consommant beaucoup de temps pour être une liste complète sur python, et appelant beaucoup de fonctions operator.add, Chacune avec sa surcharge .. Même si vous utilisez les fonctions reduce, cela n'aidera pas. C'est un problème qui doit être géré avec une approche différente: join, qui ne génère que UNE chaîne complète python, la final et appelle UNE fonction python.

(Bien sûr, join, ou toute autre fonction spécialisée similaire pour les tableaux)

4
Khelben