303

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.

2

13 Answers 13

480

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Or a genexp if you want it lazily (s + mystring for s in mylist)
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, here's a tutorial for unicode strings, docs.python.org/tutorial/introduction.html#tut-unicodestrings
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']
In case a new list was in fact not necessary, you could use slice assignment: list[:] = [x + string for x in list]
|
42
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']

Comments

9

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.

1 Comment

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.
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']

2 Comments

please change the name of the variables from list and string to something else. list is a builtin python type
This solution takes far more time to complete than the other solutions provided.
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

3 Comments

This is a good suggestion. Another one would be to use array_map with a function that appends the string... php.net/manual/en/function.array-map.php
Little typo in method 1: 'lsit2' should be 'list2'
Thanks @MortenGrum, Corrected it.
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

Comments

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']

Comments

4

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]

Comments

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

1 Comment

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)
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.

Comments

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))

Comments

0
list2 = ['%sbar' % (x,) for x in list]

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

3 Comments

Why '%sbar' % (x,) instead of '%sbar' % x? Why not x + 'bar'?
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.
'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.
0

Just in case

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.