290

I am trying to take one string, and append it to every string contained in a list, and then have a new list with the completed strings. Example:

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

*magic*

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

I tried for loops, and an attempt at list comprehension, but it was garbage. As always, any help, much appreciated.

Keiku
  • 8,205
  • 4
  • 41
  • 44
Kevin
  • 4,211
  • 10
  • 33
  • 40

13 Answers13

466

The simplest way to do this is with a list comprehension:

[s + mystring for s in mylist]

Notice that I avoided using builtin names like list because that shadows or hides the builtin names, which is very much not good.

Also, if you do not actually need a list, but just need an iterator, a generator expression can be more efficient (although it does not likely matter on short lists):

(s + mystring for s in mylist)

These are very powerful, flexible, and concise. Every good python programmer should learn to wield them.

gahooa
  • 131,293
  • 12
  • 98
  • 101
  • 10
    Or a genexp if you want it lazily `(s + mystring for s in mylist)` – Noufal Ibrahim Jan 12 '10 at 16:54
  • 3
    That definitely did the trick, thank very much, still wrapping my head around list comprehension, if you know a good tutorial on it. before each item in the list, there is a u', is that for unicode? – Kevin Jan 12 '10 at 16:58
  • 4
    @Kevin, here's a tutorial for unicode strings, http://docs.python.org/tutorial/introduction.html#tut-unicodestrings – tgray Jan 12 '10 at 17:04
  • If you need the index from the list you can do `["{}) {}".format(i, s) for i, s in enumerate(mylist)]` – Vapid Mar 11 '19 at 23:25
  • 1
    Something to note: If you add the "mystring" before the "s", rather than after, it will concatenate the "mystring" at the beginning of "s". like so `list2 = ["mystring" + s for s in mylist]` = `list2 = ['barfoo', 'barfob', 'barfaz', 'barfunk']` – Paul Tuckett May 14 '19 at 20:53
  • 1
    In case a new list was in fact not necessary, you could use slice assignment: `list[:] = [x + string for x in list]` – PYB Mar 11 '20 at 17:55
41
my_list = ['foo', 'fob', 'faz', 'funk']
string = 'bar'
my_new_list = [x + string for x in my_list]
print my_new_list

This will print:

['foobar', 'fobbar', 'fazbar', 'funkbar']
Tendayi Mawushe
  • 25,562
  • 6
  • 51
  • 57
10

map seems like the right tool for the job to me.

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

See this section on functional programming tools for more examples of map.

Nicolas Gervais
  • 33,817
  • 13
  • 115
  • 143
DMan
  • 191
  • 2
  • 4
  • This seems to be the fastest solution. If you will be repeating this process with multiple lists, you can further speed things up by defining the lambda function once and reusing it for each list. – Leland Hepworth Aug 11 '20 at 19:57
9

Here is a simple answer using pandas.

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

list2 = (pd.Series(list1) + string).tolist()
list2
# ['foobar', 'fobbar', 'fazbar', 'funkbar']
Keiku
  • 8,205
  • 4
  • 41
  • 44
7

Updating with more options

Below are some of the methods I have followed, and I'm sure there could be more.

Method 1:

list1 = ['foo', 'fob', 'faz', 'funk']
list2 = [ls+"bar" for ls in list1] # using list comprehension
print(list2)

Method 2:

list1 = ['foo', 'fob', 'faz', 'funk']
list2 = list(map(lambda ls: ls+"bar", list1))
print(list2)

Method 3:

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

Method 4:

list1 = ['foo', 'fob', 'faz', 'funk']
addstring = 'bar'
list2 = []
for value in list1:
    list2.append(str(value) + "bar")
print(list2)

Method 5:

list1 = ['foo', 'fob', 'faz', 'funk']
list2 = list(map(''.join, zip(list1, ["bar"]*len(list1))))
print(list2)

Avoid using keywords as variables like 'list', renamed 'list' as 'list1' instead

Uday Kiran
  • 659
  • 8
  • 8
6

Running the following experiment the pythonic way:

[s + mystring for s in mylist]

seems to be ~35% faster than the obvious use of a for loop like this:

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

Experiment

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)

Results

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
funk
  • 2,221
  • 1
  • 24
  • 23
5

Combining map and format:

>>> list(map('{}bar'.format,  ['foo', 'fob', 'faz', 'funk']))
['foobar', 'fobbar', 'fazbar', 'funkbar']

Thus, there is no loop variable.
It works for Python 2 and 3. (In Python 3 one can write [*map(...)], and in Python 2 just map(...).

If one prefers the modulo expression

>>> list(map('%sbar'.__mod__,  ['foo', 'fob', 'faz', 'funk']))
['foobar', 'fobbar', 'fazbar', 'funkbar']

To prepend one can use __add__ method

>>> list(map('bar'.__add__,  ['foo', 'fob', 'faz', 'funk']))
['barfoo', 'barfob', 'barfaz', 'barfunk']
2

Extending a bit to "Appending a list of strings to a list of strings":

    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)

Result:

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

dtype odject may be further converted str

Sokolokki
  • 833
  • 1
  • 9
  • 19
  • Update: You can avoid copying same symbol multiple times: `at = np.full(fill_value='@',shape=1,dtype=object)` or simply: `at = np.array("@", dtype=object)` – Sokolokki Aug 14 '18 at 10:46
2

Since Python 3.6 using f-strings is the best practice (instead of format or concatenating with +). See PEP498.

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

list2 = [f"{s}{mystring}" for s in list1]
aless80
  • 3,122
  • 3
  • 34
  • 53
1
new_list = [word_in_list + end_string for word_in_list in old_list]

Using names such as "list" for your variable names is bad since it will overwrite/override the builtins.

Nope
  • 34,682
  • 42
  • 94
  • 119
1

you can use lambda inside map in python. wrote a gray codes generator. https://github.com/rdm750/rdm750.github.io/blob/master/python/gray_code_generator.py # your code goes here ''' the n-1 bit code, with 0 prepended to each word, followed by the n-1 bit code in reverse order, with 1 prepended to each word. '''

    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))
0
list2 = ['%sbar' % (x,) for x in list]

And don't use list as a name; it shadows the built-in type.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • Why `'%sbar' % (x,)` instead of `'%sbar' % x`? Why not `x + 'bar'`? – John Machin Jan 12 '10 at 17:27
  • 1
    The second will fail if x happens to be a tuple. Obviously you *plan* to have every element be a string, but sometimes things go wrong. The difference between the first and the third is mostly taste, unless you get the string from an external source. – Ignacio Vazquez-Abrams Jan 12 '10 at 17:29
  • 3
    'raise exception' != 'fail'. If you have the wrong data type, you have *already* failed. My preferred expression raises an exception highlighting the failure; your preferred expression silently produces garbage. Taste: baroque slow expressions are not to my taste. – John Machin Jan 12 '10 at 17:45
0

Just in case

list = ['foo', 'fob', 'faz', 'funk']
string = 'bar'
for i in range(len(list)):
    list[i] += string
print(list)
tanweer alam
  • 437
  • 4
  • 6