Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing an item in list with items of another list without using dictionaries

Tags:

python

list

I am developing a function in python. Here is my content:

list = ['cow','orange','mango']
to_replace = 'orange'
replace_with = ['banana','cream']

So I want that my list becomes like this after replacement

list = ['cow','banana','cream','mango']

I am using this function:

def replace_item(list, to_replace, replace_with):
    for n,i in enumerate(list):
      if i== to_replace:
         list[n]=replace_with
    return list

It outputs the list like this:

['cow', ['banana', 'cream'], 'mango']

So how do I modify this function to get the below output?

list = ['cow','banana','cream','mango']

NOTE: I found an answer here: Replacing list item with contents of another list but I don't want to involve dictionaries in this. I also want to modify my current function only and keep it simple and straight forward.

like image 361
sshussain270 Avatar asked Sep 11 '16 20:09

sshussain270


People also ask

How do you replace an item in a list with another item in Python?

We can replace values inside the list using slicing. First, we find the index of variable that we want to replace and store it in variable 'i'. Then, we replace that item with a new value using list slicing.

How do you replace a word in a list with another in Python?

Replace a specific string in a list. If you want to replace the string of elements of a list, use the string method replace() for each element with the list comprehension. If there is no string to be replaced, applying replace() will not change it, so you don't need to select an element with if condition .

How do you replace multiple values in Python?

To replace multiple values in a DataFrame we can apply the method DataFrame. replace(). In Pandas DataFrame replace method is used to replace values within a dataframe object.


3 Answers

Modifying a list whilst iterating through it is usually problematic because the indices shift around. I recommend to abandon the approach of using a for-loop.

This is one of the few cases where a while loop can be clearer and simpler than a for loop:

>>> list_ = ['cow','orange','mango']
>>> to_replace = 'orange'
>>> replace_with = ['banana','cream']
>>> while True:
...     try:
...         i = list_.index(to_replace)
...     except ValueError:
...         break
...     else:
...         list_[i:i+1] = replace_with
...         
>>> list_
['cow', 'banana', 'cream', 'mango']
like image 106
wim Avatar answered Oct 23 '22 15:10

wim


This approach is fairly simple and has similar performance to @TadhgMcDonald-Jensen's iter_replace() approach (3.6 µs for me):

lst = ['cow','orange','mango']
to_replace = 'orange'
replace_with = ['banana','cream']

def replace_item(lst, to_replace, replace_with):
    return sum((replace_with if i==to_replace else [i] for i in lst), [])

print replace_item(lst, to_replace, replace_with)
# ['cow', 'banana', 'cream', 'mango']

Here's something similar using itertools, but it is slower (5.3 µs):

import itertools
def replace_item(lst, to_replace, replace_with):
    return list(itertools.chain.from_iterable(
            replace_with if i==to_replace else [i] for i in lst
    ))

Or, here's a faster approach using a two-level list comprehension (1.8 µs):

def replace_item(lst, to_replace, replace_with):
    return [j for i in lst for j in (replace_with if i==to_replace else [i])]

Or here's a simple, readable version that is fastest of all (1.2 µs):

def replace_item(lst, to_replace, replace_with):
    result = []
    for i in lst:
        if i == to_replace:
            result.extend(replace_with)
        else:
            result.append(i)
    return result

Unlike some answers here, these will do multiple replacements if there are multiple matching items. They are also more efficient than reversing the list or repeatedly inserting values into an existing list (python rewrites the remainder of the list each time you do that, but this only rewrites the list once).

like image 5
Matthias Fripp Avatar answered Oct 23 '22 14:10

Matthias Fripp


First off, never use python built-in names and keywords as your variable names (change the list to ls).

You don't need loop, find the index then chain the slices:

In [107]: from itertools import chain    
In [108]: ls = ['cow','orange','mango']
In [109]: to_replace = 'orange'
In [110]: replace_with = ['banana','cream']
In [112]: idx = ls.index(to_replace)  
In [116]: list(chain(ls[:idx], replace_with, ls[idx+1:]))
Out[116]: ['cow', 'banana', 'cream', 'mango']

In python 3.5+ you can use in-place unpacking:

[*ls[:idx], *replace_with, *ls[idx+1:]]
like image 3
Mazdak Avatar answered Oct 23 '22 16:10

Mazdak