Kumar
Kumar

Reputation: 77

Replace specific values in a list with values from another list

I have two lists in my python code: list_1 = [1, 'Yes', 3, 'No', 5, 'yes', 7] and list_2 = ['a', 'b', 'c']

I want to insert the value of list_2 to list_1 where it is 'yes' or 'no'.

I have tried something like this, by getting the index value of list_1 and tried to insert list_2, but it didn't work.

list_1 = [1, 'Yes', 3, 'No', 5, 'yes', 7]
list_2 = ['a', 'b', 'c']

for (each, i) in zip(list_2, range(len(list_1))):
    if list_1 == 'yes' or list_1 == 'no':
        list_1.insert(i, each)

for each in list_1:
    print(each)

I got only the output of list_1, I want my final list like this f_list=[1, 'a', 3, 'b', 5, 'c', 7] How can I achieve this?

Upvotes: 3

Views: 286

Answers (5)

balderman
balderman

Reputation: 23815

list_1 = [1, 'Yes', 3, 'No', 5, 'yes', 7]
list_2 = ['a', 'b', 'c']

idx_list = [idx for idx, x in enumerate(list_1) if isinstance(x,basestring) and x.lower() in ['yes', 'no']]
for idx, val in zip(idx_list, list_2):
    list_1[idx] = val
print(list_1)

output

[1, 'a', 3, 'b', 5, 'c', 7]

Upvotes: 0

cs95
cs95

Reputation: 402323

Convert list_2 to an iterator. You can then selectively use either list_1's value, or the next element from list_2's iterator to build a new list.

it = iter(list_2)
[next(it) if str(x).lower() in {'yes', 'no'} else x for x in list_1]
# [1, 'a', 3, 'b', 5, 'c', 7]

If the number of "yes"/"no" elements in list_1 is more than the number of elements in list_2, then you can use a function to pad list_2 with a filler value (such as None),

from itertools import chain, cycle

def pad(seq, filler=None):
    yield from chain(seq, cycle([filler]))

it = pad(list_2)
[next(it) if str(x).lower() in {'yes', 'no'} else x for x in list_1]   
# [1, 'a', 3, 'b', 5, 'c', 7]

Upvotes: 3

Kai
Kai

Reputation: 21

Pandas can do this:

import pandas as pd
list_1 = [1, 'Yes', 3, 'No', 5, 'yes', 7]
list_2 = ['a', 'b', 'c']

df_1 = pd.Series(list_1)
df_1 = df_1.replace('Yes', list_2[0])
df_1 = df_1.replace('No', list_2[1])
df_1 = df_1.replace('yes', list_2[2])

f_list = df_1.values.tolist()
print(f_list)

Upvotes: 0

Devesh Kumar Singh
Devesh Kumar Singh

Reputation: 20490

In your current approach, you are comparing the list with yes and no in the conditional if list_1 == 'yes' or list_1 == 'no': which wouldn't work, hence the if condition is never satisfied and list_1 remains as it is

A simple approach using a for loop is to look for yes and no in list_1, and once found, replace it with an element of list_2, and increment a counter to go to the next element of list_2

list_1 = [1, 'Yes', 3, 'No', 5, 'yes', 7]
list_2 = ['a', 'b', 'c']

#variable to keep track of elements of list_2
index = 0

#Iterate through indexes and item of list_1 using enumerate
for idx, item in enumerate(list_1):

    #If an item in list_1 matches yes or no
    if str(item).lower() in ['yes', 'no']:

        #Replace that item with item in list_2
        list_1[idx] = list_2[index]

        #Move to next item in list_2
        index+=1

print(list_1)

The output will be

[1, 'a', 3, 'b', 5, 'c', 7]

Upvotes: 3

gen_Eric
gen_Eric

Reputation: 227200

You can use a list comprehension to go through each element and pop one off of list_2 where needed.

list_1 = [1, 'Yes', 3, 'No', 5, 'yes', 7]
list_2 = ['a', 'b', 'c']

list_2_vals = list_2[::-1] # So we don't modify the original list_2

# Creates a new list_1 with the values we want
list_1_new = [list_2_vals.pop() if str(x).lower() in ['yes', 'no'] else x for x in list_1]

print(list_1_new)

Upvotes: 1

Related Questions