2

I have done the following snippet, a list where I went line by line and replaced the dots with commas, however in the end the list remains the same since only the line variable changes. How to update the list with the replaced values?

for line in mylist:
   line=line.replace('.',',')
   line=line.replace('a','b')

I am looking for a quick pythonic solution, other than using a 2nd list to save the replaced value. I'd like to use only 1 list, if possible and "update" it on the go.

I have multiple operations inside the for, for example in the way edited above, making the list update from the for is not possible as a "1 liner" like it's commonly done. I was looking for some sort of other way to update it if possible.

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
David
  • 1
  • 3
  • Possible duplicate of [Perform a string operation for every element in a Python list](https://stackoverflow.com/questions/7126916/perform-a-string-operation-for-every-element-in-a-python-list) – Aran-Fey Mar 19 '18 at 01:47
  • `mylist = [line.replace('.',',') for line in mylist]` – Julien Mar 19 '18 at 01:48
  • @Aran-Fey sorry, I have actually multiple operations in the for, so that 1 liner doesn't work. I am looking for some other way to update it without using a 2nd list. – David Mar 19 '18 at 01:52
  • @David There's an answer with an unrolled loop a little further down. – Aran-Fey Mar 19 '18 at 01:58

4 Answers4

2

Try:

mylist[:] = [line.replace('.',',').replace('a','b') for line in mylist]
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
0

Something along this should work:

def do_stuff(elem):
    return ...

for i in range(len(mylist)):
    mylist[i] = do_stuff(mylist[i])

or

mylist[:] = [do_stuff(line) for line in mylist]
Julien
  • 13,986
  • 5
  • 29
  • 53
  • interesting solution, i should just put the operations inside a function and call it on every line parse, won't this cause problems with local/global variables? – David Mar 19 '18 at 01:59
  • you have to be more specific about what kind of problem you are thinking... – Julien Mar 19 '18 at 02:01
  • the variables inside do_stuff will be able to work on the global mylist every time right, instead of the local mylist variable you add to the function call? – David Mar 19 '18 at 02:03
  • Not sure what you are talking about `do_stuff(mylist[i])` or `do_stuff(line)` will compute a new value, the rest of the code reassigns that new value to the original list. Try it, if you have a problem then show it explicitly and explain it clearly. – Julien Mar 19 '18 at 02:07
0

If you want to avoid creating a new list, do it like this:

for n, line in enumerate(mylist):
    mylist[n] = line.replace('.',',')

You might prefer this if the list is very long. But if you're OK with creating a new list, Stephen Rauch's solution is more "Pythonic."

Paul Cornelius
  • 9,245
  • 1
  • 15
  • 24
  • Rauch's solution only works for 1 operation, i have later specified that i will have more than 1 operation in the for, so your solution is ok. Is this more efficient than Julien's solution for example? – David Mar 19 '18 at 02:05
  • The number of operations isn't important. If you look inside the library function `replace`, it will almost certainly consist of multiple operations. If you need to call more than one library function you can write one little function of your own to return the result, as in Julien's example `do_stuff`. The real issue, probably, is whether you want to create temporarily a second copy of the list. My solution doesn't; Julien's for loop solution doesn't; Stephen's solution does and Julien's list comprehension solution does. Your choice. – Paul Cornelius Mar 19 '18 at 02:16
0

Another one solution is to use str.translate, if replacements have always one character of length.

replace = lambda x: x.translate(str.maketrans('.a', ',b'))
mylist[:] = map(replace, mylist)
brodeur
  • 96
  • 5