最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - How to Validate if a List Matches a Given Structural Pattern? - Stack Overflow

programmeradmin4浏览0评论

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 AI-generated code is forbidden in questions and answers. Be prepared for your question to be downvoted. – Barmar Commented Feb 14 at 23:55
  • 1 I'd argue a list is the wrong data structure here. What about a dict with h, eL and eR as (mandatory) keys, each mapped to an arbitrary list of strings? Or a class with he, eL, and eR attributes with string-list values? – chepner Commented Feb 15 at 5:13
  • 3 You have significantly changed the question after people have put in effort answering the original! And also submitted an AI produced attempt which does not deal with the new requirements you have introduced. – user19077881 Commented Feb 15 at 15:45
  • @user19077881 ...which is why I deleted my answer which had been functionally correct given the original question but was not correct following the [major] edit – Adon Bilivit Commented Feb 15 at 17:46
  • Can an element from fixed_elements in its proper position count as a match in a subsequent list in a test_lists list? – Chris Charley Commented Feb 15 at 20:39
Add a comment  | 

2 Answers 2

Reset to default 0

I 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)}")
发布评论

评论列表(0)

  1. 暂无评论