0

I am trying to search through triple nested lists in python. I came up with a super messy way that doesn't work. How do you do this effectively? I'm using python 3. The list I'm trying to search through is not nececarily triple nested in every slot.

Here's is the bad messy way I wrote that doesn't work for some reason.

HELLO = ["hello", "hi"]
GOODBYE = ["goodbye", "bye"]

POLITENESS = [HELLO, GOODBYE]

FRUITS = ["apples", "bananas"]
MEAT = ["pork", "chicken"]

FOODS = [FRUITS, MEAT]

random_Words = ["shoe", "bicycle", "school"]


#Here is the triple nested list.
VOCABULARY = [POLITENESS, FOODS, random_Words, "house"]

knowWord = False
userInput = input("say whatever")

#this checks for userInput in triple nested lists
#first it checks whether the first slot in vocabulary is nested,
#if that's the case it checks if the lists wiithin vocabulary[i] is nested and goes on like that.
#when finally it comes to a list that is not nested it checks for userInput in that list.

for i in range(len(VOCABULARY)):
    #if list item is not nested
    if any(isinstance(j, list) for j in VOCABULARY[i]) == False:
            #if userinput is inside a non-nested list
            if userInput not in VOCABULARY[i]:
                continue
            else:
                #if userInput is found
                knowWord = True
                break
    #if list is nested
    else:
        continue
    for k in range(len(VOCABULARY[i])):
        if any(isinstance(l, list) for l in VOCABULARY[i][k]) == False:
                if userInput not in VOCABULARY[i][k]:
                    continue
                else:
                    knowWord = True
                    break
        else:
            continue
        for m in range(len(VOCABULARY[i][k])):
            if any(isinstance(n, list) for n in VOCABULARY[i][k][m]) == False:
                    if userInput not in VOCABULARY[i][k][m]:
                        continue
                    else:
                        knowWord = True
                        break
            else:
                continue

if knowWord == True:
    print("YES")
else:
    print("I don't know that word")
Valentin Lorentz
  • 9,556
  • 6
  • 47
  • 69
  • Why not use a mapping instead of a list for `vocabulary`? – Reut Sharabani May 15 '16 at 11:32
  • 1
    Just [flatten the list](http://stackoverflow.com/a/953097). You don't seem to need the nested structure. You may also want to consider converting the resulting list to a set, so you can just do a O(1) `userInput in VOCABULARY` lookup. – ig0774 May 15 '16 at 11:44

2 Answers2

0

To make your code work you can simply remove these lines:

#if list is nested
else:
    continue

To make the code nicer, you can use recursion. This function finds out if a given word is inside however many nested lists you have:

def findWord(word,l):
    words = []
    lists = []
    for entry in l:
        if isinstance(entry,list):
            lists.append(entry)
        else:
            words.append(entry)


    for w in words:
        if w == word:
            return True

    for ls in lists:
        if findWord(word,ls) == True:
            return True

    return False



if findWord(userInput,VOCABULARY) == True:
    print("YES")
else:
    print("I don't know that word")
Keiwan
  • 8,031
  • 5
  • 36
  • 49
0

If you want to use nested lists only then below might help you, otherwise, solution mentioned above to flatten the list or converting to Set can be used also

def check(val):
    for i in itertools.chain(VOCABULARY):
        if val in i:
            return True
    return False
P. Dev
  • 27
  • 3