I am trying to write a Python function to validate whether a given list follows the same structure as a predefined "model" list, which in my particular case is:
model = [
["h", "P12", "P13"],
["P12", "P23", "eL"],
["P13", "P23", "eR"]
]
In words:
- The fixed elements
"h"
,"eL"
, and"eR"
must appear in different sublists. - The remaining elements (placeholders) -
"P12"
,"P13"
, and"P23"
- are arbitrary elements depending on the given list to test. The order of the elements is irrelevant - Repetition of the elements
"h"
,"eL"
, and"eR"
in a sublist are allowed if it fits the model structure. - The string
"P12"
must be a common element between the list that contains the element"h"
and the list that contains the string"eL"
- The string
"P13"
must be a common element between the list that contains the element"h"
and the list that contains the string"eR"
- The string
"P23"
must be a common element between the list that contains the element"eL"
and the list that contains the string"eR"
So, for example:
test_list_1 = [
["h", "a2", "a3"],
["a2", "a4", "eL"],
["a3", "a4", "eR"]
]
> True
test_list_2 = [
["h", "h", "Y"],
["h", "Z", "eL"],
["Y", "Z", "eR"]
]
> True
test_list_3 = [
["h", "X", "eL"],
["X", "Z", "eL"],
["eL", "Z", "eR"]
]
> True
test_list_4 = [
["h", "P1", "eL"],
["P1", "P3", "P2"], # ❌ there is no list containing "eL"
["P2", "P3", "eR"]
]
> False
I have tried some help with ChatGPT, but the following code is not working properly, and so far, I cannot make it work. This is my code so far with some help of AI:
from collections import defaultdict
def validate_structure(model, test_list):
fixed_elements = {"h", "eL", "eR"}
model_fixed_positions = {}
placeholder_mapping = {}
# Step 1: Identify where fixed elements appear in the model
for i, sublist in enumerate(model):
for item in sublist:
if item in fixed_elements:
model_fixed_positions[item] = i
# Step 2: Identify where fixed elements appear in the test list
test_fixed_positions = {}
for i, sublist in enumerate(test_list):
for item in sublist:
if item in fixed_elements:
if item in test_fixed_positions:
return False # Each fixed element must be in a distinct sublist
test_fixed_positions[item] = i
# Step 3: Ensure fixed elements are in corresponding positions
if set(model_fixed_positions.keys()) != set(test_fixed_positions.keys()):
return False # Missing or extra fixed elements
for key in model_fixed_positions:
if model_fixed_positions[key] != test_fixed_positions[key]:
return False # Fixed elements must appear in the same indexed sublists
# Step 4: Establish and validate placeholder mapping
for i, (model_sublist, test_sublist) in enumerate(zip(model, test_list)):
model_placeholders = [x for x in model_sublist if x not in fixed_elements]
test_placeholders = [x for x in test_sublist if x not in fixed_elements]
if len(model_placeholders) != len(test_placeholders):
return False # Different number of elements
for m_item, t_item in zip(model_placeholders, test_placeholders):
if m_item in placeholder_mapping:
if placeholder_mapping[m_item] != t_item:
return False # Inconsistent placeholder mapping
else:
placeholder_mapping[m_item] = t_item
return True # Structure matches
# Example usage:
print(validate_structure(model, test_list_2)) # Expected: True, but returns False
I am trying to write a Python function to validate whether a given list follows the same structure as a predefined "model" list, which in my particular case is:
model = [
["h", "P12", "P13"],
["P12", "P23", "eL"],
["P13", "P23", "eR"]
]
In words:
- The fixed elements
"h"
,"eL"
, and"eR"
must appear in different sublists. - The remaining elements (placeholders) -
"P12"
,"P13"
, and"P23"
- are arbitrary elements depending on the given list to test. The order of the elements is irrelevant - Repetition of the elements
"h"
,"eL"
, and"eR"
in a sublist are allowed if it fits the model structure. - The string
"P12"
must be a common element between the list that contains the element"h"
and the list that contains the string"eL"
- The string
"P13"
must be a common element between the list that contains the element"h"
and the list that contains the string"eR"
- The string
"P23"
must be a common element between the list that contains the element"eL"
and the list that contains the string"eR"
So, for example:
test_list_1 = [
["h", "a2", "a3"],
["a2", "a4", "eL"],
["a3", "a4", "eR"]
]
> True
test_list_2 = [
["h", "h", "Y"],
["h", "Z", "eL"],
["Y", "Z", "eR"]
]
> True
test_list_3 = [
["h", "X", "eL"],
["X", "Z", "eL"],
["eL", "Z", "eR"]
]
> True
test_list_4 = [
["h", "P1", "eL"],
["P1", "P3", "P2"], # ❌ there is no list containing "eL"
["P2", "P3", "eR"]
]
> False
I have tried some help with ChatGPT, but the following code is not working properly, and so far, I cannot make it work. This is my code so far with some help of AI:
from collections import defaultdict
def validate_structure(model, test_list):
fixed_elements = {"h", "eL", "eR"}
model_fixed_positions = {}
placeholder_mapping = {}
# Step 1: Identify where fixed elements appear in the model
for i, sublist in enumerate(model):
for item in sublist:
if item in fixed_elements:
model_fixed_positions[item] = i
# Step 2: Identify where fixed elements appear in the test list
test_fixed_positions = {}
for i, sublist in enumerate(test_list):
for item in sublist:
if item in fixed_elements:
if item in test_fixed_positions:
return False # Each fixed element must be in a distinct sublist
test_fixed_positions[item] = i
# Step 3: Ensure fixed elements are in corresponding positions
if set(model_fixed_positions.keys()) != set(test_fixed_positions.keys()):
return False # Missing or extra fixed elements
for key in model_fixed_positions:
if model_fixed_positions[key] != test_fixed_positions[key]:
return False # Fixed elements must appear in the same indexed sublists
# Step 4: Establish and validate placeholder mapping
for i, (model_sublist, test_sublist) in enumerate(zip(model, test_list)):
model_placeholders = [x for x in model_sublist if x not in fixed_elements]
test_placeholders = [x for x in test_sublist if x not in fixed_elements]
if len(model_placeholders) != len(test_placeholders):
return False # Different number of elements
for m_item, t_item in zip(model_placeholders, test_placeholders):
if m_item in placeholder_mapping:
if placeholder_mapping[m_item] != t_item:
return False # Inconsistent placeholder mapping
else:
placeholder_mapping[m_item] = t_item
return True # Structure matches
# Example usage:
print(validate_structure(model, test_list_2)) # Expected: True, but returns False
Share
Improve this question
edited Feb 15 at 13:09
SNC92
asked Feb 14 at 23:37
SNC92SNC92
113 bronze badges
5
|
2 Answers
Reset to default 0I used sets to check for membership (and only allowed the members P12, P13 and P23
to be considered to match.
test_list_1 = [
["h", "a2", "a3"],
["a2", "a4", "eL"],
["a3", "a4", "eR"]
]
test_list_2 = [
["h", "h", "Y"],
["h", "Z", "eL"],
["Y", "Z", "eR"]
]
test_list_3 = [
["h", "X", "eL"],
["X", "Z", "eL"],
["eL", "Z", "eR"]
]
test_list_4 = [
["h", "P1", "eL"],
["P1", "P3", "P2"], # ❌ there is no list containing "eL"
["P2", "P3", "eR"]
]
test_list_5 = [["h", "h", "Y"], ["h", "Z", "eL"], ["k", "Z", "eR"]]
model = [
["h", "P12", "P13"],
["P12", "P23", "eL"],
["P13", "P23", "eR"]
]
def validate(test_list, model):
fixed_vals = ["h", "eL", "eR"]
for value, model_array, test_array in zip(fixed_vals, model, test_list):
idx = model_array.index(value)
if value != test_array[idx]:
return False
sets = []
for i in range(len(test_list)):
s = set(test_list[i])
if 1 == test_list[i].count(fixed_vals[i]):
s.remove(fixed_vals[i])
sets.append(s)
#sets = list(map(set, test_list))
# only if fixed elements in postion sre allowed to match
# I don't think thats allowed by his specifications
# in test_list_3 the 'Z's match, not the 'eL's
for i in range(len(sets)):
for j in range(i+1, len(sets)):
if len(sets[i] & sets[j]) == 0:
return False
return True
print(validate(test_list_1, model))
print(validate(test_list_2, model))
print(validate(test_list_3, model))
print(validate(test_list_4, model))
print(validate(test_list_5, model))
Prints:
True
True
True
False
False
I looked it as a recursion problem. Used dictionary where keys are your fixed elements and indexes (paths) are in the tuples. Used those data structures because they are hashtables, in general good big-O
P.S. For your PROD code never test like me above, write asserts
def recursive_scan(data, fixed_elements, path=()):
positions = {key: [] for key in fixed_elements}
if isinstance(data, list):
for index, element in enumerate(data):
new_path = path + (index,)
if element in fixed_elements:
positions[element].append(new_path)
elif isinstance(element, list):
sub_positions = recursive_scan(element, fixed_elements, new_path)
for key in sub_positions:
positions[key].extend(sub_positions[key])
return positions
def check_structure_match(model_structure, test_structure):
for key in model_structure:
model_positions = set(model_structure[key])
test_positions = set(test_structure[key])
# Check if all model positions exist in the test (extra occurrences are ignored)
if not model_positions.issubset(test_positions):
return False
return True
MODEL = [["h", "P12", "P13"], ["P12", "P23", "eL"], ["P13", "P23", "eR"]]
FIXED_ELEMENTS = ["h", "eL", "eR"]
model_structure = recursive_scan(MODEL, FIXED_ELEMENTS)
test_cases = {
"test_list_2": [["h", "h", "Y"], ["h", "Z", "eL"], ["Y", "Z", "eR"]],
"test_list_3": [["h", "X", "eL"], ["X", "Z", "eL"], ["eL", "Z", "eR"]],
"test_list_4": [["h", "P1", "eL"], ["P1", "P3", "P2"], ["P2", "P3", "eR"]],
}
for test_name, test_list in test_cases.items():
test_structure = recursive_scan(test_list, FIXED_ELEMENTS)
print(f"{test_name}: {check_structure_match(model_structure, test_structure)}")
dict
withh
,eL
andeR
as (mandatory) keys, each mapped to an arbitrary list of strings? Or a class withhe
,eL
, andeR
attributes with string-list values? – chepner Commented Feb 15 at 5:13