Ajouter la même chaîne à une liste de chaînes en Python

199

J'essaie de prendre une chaîne et de l'ajouter à chaque chaîne contenue dans une liste, puis d'avoir une nouvelle liste avec les chaînes complétées. Exemple:

list1 = ['foo', 'fob', 'faz', 'funk']
string = 'bar'

*magic*

list2 = ['foobar', 'fobbar', 'fazbar', 'funkbar']

J'ai essayé des boucles et une tentative de compréhension de liste, mais c'était des ordures. Comme toujours, toute aide, très appréciée.

Kevin
la source
26
Il n'est pas judicieux d'attribuer listcar il s'agit d'un fichier intégré.
Noufal Ibrahim

Réponses:

337

Le moyen le plus simple de le faire est de comprendre une liste:

[s + mystring for s in mylist]

Notez que j'ai évité d'utiliser des noms intégrés comme listparce que cela ombres ou masque les noms intégrés, ce qui n'est vraiment pas bon.

De plus, si vous n'avez pas réellement besoin d'une liste, mais avez simplement besoin d'un itérateur, une expression de générateur peut être plus efficace (même si cela n'a probablement pas d'importance sur les listes courtes):

(s + mystring for s in mylist)

Ceux-ci sont très puissants, flexibles et concis. Tout bon programmeur python devrait apprendre à les manier.

gahooa
la source
8
Ou un genexp si vous le voulez paresseusement(s + mystring for s in mylist)
Noufal Ibrahim
1
Cela a vraiment fait l'affaire, merci beaucoup, toujours à la compréhension de la liste, si vous connaissez un bon tutoriel à ce sujet. avant chaque élément de la liste, il y a un u ', est-ce pour unicode?
Kevin
3
@Kevin, voici un tutoriel pour les chaînes Unicode, docs.python.org/tutorial/introduction.html#tut-unicodestrings
tgray
1
A noter: si vous ajoutez le "mystring" avant le "s", plutôt qu'après, il concaténera le "mystring" au début de "s". like so list2 = ["mystring" + s for s in mylist]=list2 = ['barfoo', 'barfob', 'barfaz', 'barfunk']
Paul Tuckett
1
Au cas où une nouvelle liste ne serait en fait pas nécessaire, vous pouvez utiliser l'affectation de tranche:list[:] = [x + string for x in list]
PYB
26
my_list = ['foo', 'fob', 'faz', 'funk']
string = 'bar'
my_new_list = [x + string for x in my_list]
print my_new_list

Cela imprimera:

['foobar', 'fobbar', 'fazbar', 'funkbar']
Tendayi Mawushe
la source
6

map me semble être le bon outil pour le travail.

my_list = ['foo', 'fob', 'faz', 'funk']
string = 'bar'
list2 = list(map(lambda orig_string: orig_string + string, my_list))

Voir cette section sur les outils de programmation fonctionnelle pour plus d'exemples de map.

DMan
la source
Cela semble être la solution la plus rapide. Si vous répétez ce processus avec plusieurs listes, vous pouvez accélérer les choses en définissant une fois la fonction lambda et en la réutilisant pour chaque liste.
Leland Hepworth
4

Voici une réponse simple en utilisant pandas.

import pandas as pd
list1 = ['foo', 'fob', 'faz', 'funk']
string = 'bar'

list2 = (pd.Series(list1) + string).tolist()
list2
# ['foobar', 'fobbar', 'fazbar', 'funkbar']
Keiku
la source
veuillez changer le nom des variables de liste et chaîne en autre chose. list est un type python intégré
sagi
Cette solution prend beaucoup plus de temps que les autres solutions proposées.
Leland Hepworth
3

Lancer l'expérience suivante à la manière pythonique:

[s + mystring for s in mylist]

semble être ~ 35% plus rapide que l'utilisation évidente d'une boucle for comme celle-ci:

i = 0
for s in mylist:
    mylist[i] = s+mystring
    i = i + 1

Expérience

import random
import string
import time

mystring = '/test/'

l = []
ref_list = []

for i in xrange( 10**6 ):
    ref_list.append( ''.join(random.choice(string.ascii_lowercase) for i in range(10)) )

for numOfElements in [5, 10, 15 ]:

    l = ref_list*numOfElements
    print 'Number of elements:', len(l)

    l1 = list( l )
    l2 = list( l )

    # Method A
    start_time = time.time()
    l2 = [s + mystring for s in l2]
    stop_time = time.time()
    dt1 = stop_time - start_time
    del l2
    #~ print "Method A: %s seconds" % (dt1)

    # Method B
    start_time = time.time()
    i = 0
    for s in l1:
        l1[i] = s+mystring
        i = i + 1
    stop_time = time.time()
    dt0 = stop_time - start_time
    del l1
    del l
    #~ print "Method B: %s seconds" % (dt0)

    print 'Method A is %.1f%% faster than Method B' % ((1 - dt1/dt0)*100)

Résultats

Number of elements: 5000000
Method A is 38.4% faster than Method B
Number of elements: 10000000
Method A is 33.8% faster than Method B
Number of elements: 15000000
Method A is 35.5% faster than Method B
trouille
la source
2

Étendre un peu à "Ajout d'une liste de chaînes à une liste de chaînes":

    import numpy as np
    lst1 = ['a','b','c','d','e']
    lst2 = ['1','2','3','4','5']

    at = np.full(fill_value='@',shape=len(lst1),dtype=object) #optional third list
    result = np.array(lst1,dtype=object)+at+np.array(lst2,dtype=object)

Résultat:

array(['a@1', 'b@2', 'c@3', 'd@4', 'e@5'], dtype=object)

dtype odject peut être davantage converti str

Artur Sokolovsky
la source
Mise à jour: Vous pouvez éviter de copier le même symbole plusieurs fois: at = np.full(fill_value='@',shape=1,dtype=object) ou simplement: at = np.array("@", dtype=object)
Artur Sokolovsky
1

vous pouvez utiliser lambda à l'intérieur de la carte en python. a écrit un générateur de codes gris. https://github.com/rdm750/rdm750.github.io/blob/master/python/gray_code_generator.py # votre code va ici '' 'le code n-1 bits, avec 0 en préfixe à chaque mot, suivi du Code de n-1 bits dans l'ordre inverse, avec 1 précédé de chaque mot. '' '

    def graycode(n):
        if n==1:
            return ['0','1']
        else:
            nbit=map(lambda x:'0'+x,graycode(n-1))+map(lambda x:'1'+x,graycode(n-1)[::-1])
            return nbit

    for i in xrange(1,7):
        print map(int,graycode(i))
Rohit Malgaonkar
la source
1

Mise à jour avec plus d'options

list1 = ['foo', 'fob', 'faz', 'funk']
addstring = 'bar'
for index, value in enumerate(list1):
    list1[index] = addstring + value #this will prepend the string
    #list1[index] = value + addstring this will append the string

Évitez d'utiliser des mots clés en tant que variables telles que "liste", renommée "liste" en "liste1" à la place

Uday Kiran
la source
C'est une bonne suggestion. Un autre serait d'utiliser array_map avec une fonction qui ajoute la chaîne ... php.net/manual/en/function.array-map.php
ROunofF
0
list2 = ['%sbar' % (x,) for x in list]

Et ne l'utilisez pas listcomme nom; il masque le type intégré.

Ignacio Vazquez-Abrams
la source
Pourquoi '%sbar' % (x,)au lieu de '%sbar' % x? Pourquoi pas x + 'bar'?
John Machin
1
Le second échouera si x est un tuple. Évidemment, vous prévoyez que chaque élément soit une chaîne, mais parfois les choses tournent mal. La différence entre le premier et le troisième est principalement le goût, à moins que vous n'obteniez la chaîne d'une source externe.
Ignacio Vazquez-Abrams
2
'lever exception'! = 'échouer'. Si vous avez le mauvais type de données, vous avez déjà échoué. Mon expression préférée soulève une exception soulignant l'échec; votre expression préférée produit silencieusement des déchets. Goût: les expressions lentes baroques ne sont pas à mon goût.
John Machin
0
new_list = [word_in_list + end_string for word_in_list in old_list]

Utiliser des noms tels que "list" pour vos noms de variables est mauvais car cela écrasera / remplacera les fonctions intégrées.

Nan
la source
0

Au cas où

list = ['foo', 'fob', 'faz', 'funk']
string = 'bar'
for i in range(len(list)):
    list[i] += string
print(list)
Tanweer Alam
la source