Reputation: 13
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
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
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