Iterating through a list for specific instances

Question:

I have the following code:

paths = [['E', 'D', 'A', 'B'], ['E', 'D', 'A', 'C', 'B'], ['E', 'D', 'B'], ['E', 'D', 'C', 'B'], ['E', 'B'], ['E', 'C', 'B']]

Now, the lists inside a list represent node paths from start to end which were made using Networkx, however that is some background information. My question is more specific.

I am trying to derive the lists that only have every letter from A-E, aka it would return only the list:

paths_desired = [['E', 'D', 'A', 'C', 'B']]

If I were to have another path:

paths = [['E', 'D', 'A', 'B'], ['E', 'D', 'A', 'C', 'B'], ['D', 'B', 'A','C','E'], ['A', 'D', 'C', 'B']]

It would return:

paths_desired = [['E', 'D', 'A', 'C', 'B'],['D', 'B', 'A', 'C', 'E']]

My idea is a for loop that iterates through each list:

for i in pathways:
    counter = 0
    for j in letters:
        if j in i:
            counter = counter + 1;
    if counter == 5:
        desired_paths.append(i)
        
print(desired_paths)

This works, however, I want to make the loop more specific, meaning I want only lists that have the following order: [‘E’,’D’,’A’,’C’,’B’], even if all the letters are present in a different list, within the paths list.

Additionally, is there a way I can upgrade my for loop, so that I wouldn’t count, rather check if the letters are in there, and not more than 1 of each letter? Meaning no multiple Es, no multiple D, etc.

Asked By: PKrange

||

Answers:

You can use a use a set and .issubset() like this:

def pathways(letters, paths):
    ret = []
    letters = set(letters)
    for path in paths:
        if letters.issubset(path):
            ret.append(path)
    return ret


letters = ['A', 'B', 'C', 'D', 'E']
paths = [['E', 'D', 'A', 'B'], ['E', 'D', 'A', 'C', 'B'],
         ['D', 'B', 'A','C','E'], ['A', 'D', 'C', 'B']]
print(pathways(letters, paths))  # => [['E', 'D', 'A', 'C', 'B'], ['D', 'B', 'A', 'C', 'E']]

Also, as a comment by ShadowRanger pointed out, the pathways() function could be shortened using filter(). Like this:

def pathways(letters, paths):
    return list(filter(set(letters).issubset, paths))


letters = ['A', 'B', 'C', 'D', 'E']
paths = [['E', 'D', 'A', 'B'], ['E', 'D', 'A', 'C', 'B'],
         ['D', 'B', 'A','C','E'], ['A', 'D', 'C', 'B']]
print(pathways(letters, paths))
Answered By: Michael M.
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.