Replace elements in a list of lists python
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.
KRB
Updated on June 22, 2022Comments
-
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 over 5 yearsThe "more pythonic" part isn't really a generic one considering the fact that
bob
can come anywhere in the sublist. -
jpp over 5 years@Austin, Possibly. Given the example input, I'm happy to wait a little longer before making it more generic :)
-
Austin over 5 yearsUsing
replace
with list-comprehension seems handle all cases, but then it's upto OP. :) -
jpp over 5 years@Austin, Now I'm worried about someone called
mobob
being renamedmob
. -
Jon Clements over 5 years@jpp don't forget poor "bobby" :)
-
Austin over 5 yearsLol. If you think so, use
if a == 'bob':
instead ofif 'bob' in a:
. -
vash_the_stampede over 5 yearsor bobaganoush hahah
-
Tenserflu almost 3 yearsI was looking for this. Many thanks! @lu5er