BadTagQuester
BadTagQuester

Reputation: 13

Pattern in one list to compare another list

I am working on a program which has two lists with the same amount of elements

The first list consists of a pattern (Note: pat will always have atleast 2 different elements):

pat = ['G', 'H', 'G' ]

Then the second list is a list that contains lists.

mylist = [['Hello'], ['Hey'], ['Hello']]

I need to check the pattern in pat, and see if mylist follows the pattern.

So in this case mylist follows the pattern in pat because mylist[0] == mylist[2] and mylist[1] could be anything because it doesnt have to follow any other pattern according to pat.

So the program should return the elements in mylist which DO NOT follow the pattern in pat:

[]

But if mylist did not follow the pattern in pat, then the program should return a list with only the elements in mylist which did not follow the patter in the same order, here are some function calls:

>>>pat_check(['G', 'W', 'G', 'G'], [[12], ['E'], [12], [13]])    #[13], [12], [12] should be the same but they are not therefor the program returns all those values
[[12], [12], [13]]

>>>pat_check(['G', 'H', 'G'], [['G'], ['H'], ['L']])    #['G'] and ['L'] are supposed to be the same but they are not, the program will output the 2 elements that should be the same but are not
[['G'], ['L']]

>>>pat_check(['G', 'H', 'G'], [['Hello'], ['Hey'], ['Hello']])  # everything is correct
[]

I am really new to python, it would be really appreciated to use easy to understand form and just basic methods. (no import re and other stuff like that)

Q: Is there any algorithm to do this?

Upvotes: 0

Views: 319

Answers (2)

ThinkChaos
ThinkChaos

Reputation: 1843

Use a dict to keep track of what you encountered:

def pat_check(pat, mylist):
    dct = {}
    res = []
    for p, q in zip(pat, mylist):
        if dct.setdefault(p, q) != q:
            res.append(q)
    return res

Note: You have to add code to handle pat and mylist of different lengths.

Also, pat_check(['G', 'H', 'G'], [['G'], ['H'], ['L']]) should be [['L']], which is not what you wrote in your post.

Using list comprehension:

def pat_check(pat, mylist):
    dct = {}
    return [q for p, q in zip(pat, mylist) if dct.setdefault(p, q) != q]

EDIT:

from collections import defaultdict


def key_vals(pat, mylist):
    res = defaultdict(list)
    for p, q in zip(pat, mylist):
        res[p].append(q)
    return res


def pat_check(pat, mylist):
    res = []
    for p, vals in key_vals_order(pat, mylist).items():
        # could be vals[1:], but that makes a copy so it should be benched with
        # actual data
        if any(v != vals[0] for v in vals):
            res.extend(vals)
    return res

If you care about order:

from collections import OrderedDict


def key_vals(pat, mylist):
    res = OrderedDict()
    for p, q in zip(pat, mylist):
        res.setdefault(p, []).append(q)
    return res

Upvotes: 1

Kyle_S-C
Kyle_S-C

Reputation: 1177

Maybe try something like this:

def pat_check(pattern, list_to_check):
    pattern_dict = {}
    not_matching = []
    for i, value in enumerate(pattern):
        try:
            if pattern_dict[value] != list_to_check[i]:
                not_matching.append(list_to_check[i])
        except KeyError:
            pattern_dict[value] = list_to_check[i]
    return not_matching

Bear in mind that there's a bit of an ambiguous situation in your example:

pat_check(['G', 'H', 'G'], [['G'], ['H'], ['L']]) #['G'] and ['L'] are supposed to be the same but they are not [['G'], ['L']]

This algorithm only outputs ['L'] as it considers ['G'] to match with itself.

Upvotes: 0

Related Questions