3

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?

2
  • 2
    What if the number of "yes"/"no" is more than the elements in list_2? Commented Jun 21, 2019 at 14:45
  • This is a good question, so if the number of Yes or No is more, then it can remain as Yes or No, but if the number of values in the list_2 is more, then I want it to be appended at the end of list_1. Thanks Commented Jun 21, 2019 at 15:24

5 Answers 5

3

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]
Sign up to request clarification or add additional context in comments.

Comments

3

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]

7 Comments

Like the set lookup in str(x).lower() in {'yes', 'no'} , and ofcourse there is a iterator based approach lol! Have my upvote :)
@DeveshKumarSingh Funnily enough I believe the interpreter converts {a, b} to (a, b) so using a set or tuple makes no difference. :)
Nice use of iter()! I was trying to pop off the top of the list, so my solution required reversing the list then using pop().
But either of them is better than a list right like I did ? @cs95 or for such a small list, the difference is negligible?
@DeveshKumarSingh Yes, it very much likely is a difference on the scale of "don't worry about it".
|
1

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)

Comments

0

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)

Comments

0
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]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.