I need a little bit of help. I'm stuck on how to approach this one. So the general idea is to have a function taking 3 inputs. First is a list, second is also a list, but it contains values which are considered to be indexes and third is one value. The goal is to check if value in second list matches any index in first list and in case it does it should replace it by the value of third parameter.
I have something like this, but it doesn't work properly.
def sub(original, replace, new_value):
for item in replace:
for index in range(len(original)):
if original[index] == item:
original[index] = new_value
return original
Examples of how it is supped to look:
sub([1, 2, 3, 4, 5], [2, 3], 'H') -> [1, 2, 'H', 'H', 5]
sub([1, 2, 3, 4, 5], [0, 10], 50) -> [50, 2, 3, 4, 5]
My output is like this
[1, 'a', 'a', 4, 5]
CodePudding user response:
Here's the most obvious way to do this:
def sub(original, replace, new_value):
for index in range(len(original)):
if index in replace:
original[index] = new_value
return original
However, the test for index
being in replace
is linear, which is suboptimal. It's preferable to create a set up front, then use the set for the membership test:
def sub(original, replace, new_value):
replace_set = set(replace)
for index in range(len(original)):
if index in replace_set:
original[index] = new_value
return original
These both produce the desired result. The second will be faster for long lists.
Note that these solutions are both "destructive", in that they modify the list passed in through original
. If you don't want to modify that list, you can use a list comprehension to create a new list, as follows:
def sub(original, replace, new_value):
replace_set = set(replace)
return [new_value if ix in replace_set else v
for ix, v in enumerate(original)]
The returned list is still the desired result, but the original list is unchanged.