Replace elements in a list of lists python

18,693

Solution 1

Because str.replace doesn't work in-place, it returns a copy. As immutable objects, you need to assign the strings to elements in your list of lists.

You can assign directly to your list of lists if you extract indexing integers via enumerate:

L = [['a','bob'],['a','bob'],['a','john']]

for i, x in enumerate(L):
    for j, a in enumerate(x):
        if 'bob' in a:
            L[i][j] = a.replace('bob', 'b')

Result:

[['a', 'b'], ['a', 'b'], ['a', 'john']]

More Pythonic would be to use a list comprehension to create a new list. For example, if only the second of two values contains names which need checking:

L = [[i, j if j != 'bob' else 'b'] for i, j in L]

Solution 2

You can try using a dictionary object of python

import numpy as np
L = [['a','bob'],['a','bob'],['a','john']]
dic = {'bob':'b'} # you can specify more changes here
new_list = [dic.get(n, n) for n in np.concatenate(L)]
print(np.reshape(new_list,[-1,2]).tolist())

Result is

[['a', 'b'], ['a', 'b'], ['a', 'john']]

Solution 3

I'm going to use a simple example, but basically x is another variable and isn't linked to the list element. You have to change the list element directly in order to alter the list.

l=[1,2,3,4]
for x in l:
    x=x+1

This doesn't change the list

l=[1,2,3,4]
for i,x in enumerate(l):
    l[i]=x+1

this changes the list

Solution 4

I might be a little to the party, but a more Pythonic way of doing this is using a map and a list comprehension. It can operate on a list of the list with any number of values.

l = [['a','bob'],['a','bob'],['a','john']]

[list(map(lambda x: x if x != 'bob' else 'b', i)) for i in l]

it gives you the desired output

[['a', 'b'], ['a', 'b'], ['a', 'john']]

The main idea is that the inner loop is iterating through the inner loop and using the simple lambda function to perform the replacement.

I hope that this helps anyone else who is looking out for something similar.

Share:
18,693
KRB
Author by

KRB

Updated on June 22, 2022

Comments

  • KRB
    KRB almost 2 years

    I have a list of lists as follows:

         list=[]
         *some code to append elements to list*
    
         list=[['a','bob'],['a','bob'],['a','john']]
    

    I want to go through this list and change all instances of 'bob to 'b' and leave others unchanged.

        for x in list:
           for a in x:
              if "bob" in a:
                 a.replace("bob", 'b')
    

    After printing out x it is still the same as list, but not as follows:

        list=[['a','b'],['a','b'],['a','john']]
    

    Why is the change not being reflected in list?

  • Austin
    Austin over 5 years
    The "more pythonic" part isn't really a generic one considering the fact that bob can come anywhere in the sublist.
  • jpp
    jpp over 5 years
    @Austin, Possibly. Given the example input, I'm happy to wait a little longer before making it more generic :)
  • Austin
    Austin over 5 years
    Using replace with list-comprehension seems handle all cases, but then it's upto OP. :)
  • jpp
    jpp over 5 years
    @Austin, Now I'm worried about someone called mobob being renamed mob.
  • Jon Clements
    Jon Clements over 5 years
    @jpp don't forget poor "bobby" :)
  • Austin
    Austin over 5 years
    Lol. If you think so, use if a == 'bob': instead of if 'bob' in a:.
  • vash_the_stampede
    vash_the_stampede over 5 years
    or bobaganoush hahah
  • Tenserflu
    Tenserflu almost 3 years
    I was looking for this. Many thanks! @lu5er