0

Good day coders, I have 2 lists:

A = ['yes', 'red', 'car']
B = ['yes', ['yellow', 'red'], 'car']

I am trying to take items from list A and then loop through list B and see if item-A is in list B (List B is has a nested list). i tried to use a for loop like so:

for item in A:
    if item in B:
        print(item,'is a correct answer.')
    else:
        print(item,'is a wrong answer.')

desired output 3 correct answer and the list B to be empty because after fiding a match, items from list be get popped out:

yes is a correct answer
red is a correct answer
car is a correct answer
List B = []


pardon my question structure, i am new to this. and thanks for helping =)

  • 1
    To clarify, how should the nested list be handled, should the code check whether the item being checked for is included in any of the sublists or only whether the item is one of the top-level items? – Otto Hanski Jul 20 '22 at 09:29
  • can you add a desired output? – Nin17 Jul 20 '22 at 09:29
  • You might want to check `itertools.chain` to flatten the second list and compare them – ChatterOne Jul 20 '22 at 09:31
  • @ChatterOne they seem to have that nested list of varying depth, `chain` won't help with that, likely a recursive solution as mentioned here would help with flattening the list: https://stackoverflow.com/questions/12472338/flattening-a-list-recursively – Matiiss Jul 20 '22 at 09:32
  • @OttoHanski the item in A should be compared against the entirety of list B, top level and nested are included , so item-A would jump inside the nested lists, then jump out to the higher level, and again jump in any other nested list in the B List. – Infinite_Code Jul 20 '22 at 10:29
  • @ChatterOne i dont want to flatten the list because i also want to pop out that nested list once a match was found. – Infinite_Code Jul 20 '22 at 10:34

4 Answers4

3

One approach to handle arbitrarily nested lists:

def flatten(x):
    for e in x:
        if isinstance(e, list):
            yield from flatten(e)
        else:
            yield e


A = ['yes', 'red', 'car']
B = ['yes', ['yellow', 'red'], 'car']

for bi in flatten(B):
    if bi in A:
        print(bi)

Output

yes
red
car
Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76
  • 2
    this is about the cleanest way of flattening a list I have seen – Matiiss Jul 20 '22 at 09:36
  • Thanks for teaching me this flatten technique, but actually i do not wish to flatten List B because after item A finds a match in list b, i want to pop out the item in list b, whether its a single item or a nested list, do you understand me? – Infinite_Code Jul 20 '22 at 10:37
  • @Infinite_Code Please add the corresponding output in the question, so I can have a better idea of what you mean – Dani Mesejo Jul 20 '22 at 10:39
  • @DaniMesejo i did include it now , please have a look at the last code snippet. – Infinite_Code Jul 20 '22 at 11:53
0

Try this:

def flatten(lst):
    if not lst:
        return lst
    if isinstance(lst[0], list):
        return flatten(lst[0]) + flatten(lst[1:])
    return lst[:1] + flatten(lst[1:])

A = ['yes', 'red', 'car']
B = ['yes', ['yellow', 'red'], 'car']
C = flatten(B)

for item in A:
    if item in C:
        print(item, 'is in list B')
    else:
        print(item, 'is not in list B')

Output:

yes is in list B
red is in list B
car is in list B
The Thonnu
  • 3,578
  • 2
  • 8
  • 30
0

Maybe pandas.explode helps:

import pandas as pd
A = ['yes', 'red', 'car', 'test']
B = ['yes', ['yellow', 'red'], 'car']

for item in A:
    print(item, item in pd.DataFrame(B).explode(0)[0].tolist())

Result:

yes True
red True
car True
test False
René
  • 4,594
  • 5
  • 23
  • 52
  • I updated my answer. Hope solves the issue. – René Jul 20 '22 at 09:48
  • 1
    wow, `pandas` doing magic again, always amazed at what can be done with that library, does `explode` flatten it completely or does this work only with one level of nesting? oh, I suppose it flattens it completely, but you could also save `pd.DataFrame(B).explode(0)[0].tolist()` to a variable to avoid calling all that stuff every iteration – Matiiss Jul 20 '22 at 09:48
  • not sure if you noticed but you could do `exploded_b = pd.DataFrame(B).explode(0)[0].tolist()` and then use `item in exploded_b` or sth along that, that would improve the performance quite a bit – Matiiss Jul 20 '22 at 09:59
  • @Rene this explode() method does flatten the list B, correct ? it does amazing job. however, i actually do not want to explode list B, because item-A finds a match in list B (whether high level match , or inside a nested list) , i want to pop out that item from item.. thats why i want list B to stay intact, you understand me? – Infinite_Code Jul 20 '22 at 10:44
0

You can also solve it without flattening:

  for item in B:
    if item in A:
      print(item,'is a correct answer.')
    elif isinstance(item, list):
        for nested_item in item:
            if nested_item in A:
                print(nested_item,'is a correct answer.')
            else:
                print(nested_item,'is a wrong answer.')
    else:
        print(item,'is a wrong answer.')

But note that this solution does not eliminate the duplicates. If you do want to do that create a list of values which are in both lists and which are in A but but not in B and eliminate the duplicates by list(dict.fromkeys(mylist)), where mylist is the considered list.

Kateryna
  • 36
  • 3
  • and what if there is a greater nesting level? – Matiiss Jul 20 '22 at 09:46
  • it wasn't specified – Kateryna Jul 20 '22 at 09:51
  • they said it's a nested list, nesting level was not mentioned so you should provide a solution that works for any nesting level, exactly the fact that the nesting level is not specified should mean that the answer should work with any nesting level, it's not like you can efficiently show an arbitrary level of nesting, if they had a nesting level of 2, so a list inside a list inside a list, would you then make another nested for loop? that's rather inefficient and at that point generic solutions should be provided – Matiiss Jul 20 '22 at 09:54