How to iterate through list and replace attribute with another list with same attribute Python

78 views Asked by At

I want to write some code that for the list 'paths', checks each path, and checks each edge inside the path and if one of the vertice in the edge is equal to a vertice in a cycle, it adds the cycle onto the path. This is just an example, but for a path there maybe be multiple connecting cycles at any point of the path if that makes sense. The code I have written adds the cycles twice and in it's own list rather than individual edges.

paths = [
    [[1, 2]],
    [[1, 2], [2, 3], [3, 4]],
    [[1, 2], [2, 3], [3, 8], [8, 9], [9, 10]]
    ]

cycles = [
    [[10, 11], [11, 12], [12, 10]],
    [[4, 5], [5, 6], [6, 7], [7, 4]]
    ]

for current_path in paths:
    for path_edge in current_path:
        for path_vertice in path_edge:
            for cycles_i in cycles:
                for cycles_edge in cycles_i:
                    for cycles_vertice in cycles_edge:
                        if path_vertice == cycles_vertice:
                            path_edge.append(cycles_i)

# output I get
paths = [
    [[1, 2]],
    [[1, 2], [2, 3], [3, 4, [[4, 5], [5, 6], [6, 7], [7, 4]], [[4, 5], [5, 6], [6, 7], [7, 4]]]],
    [[1, 2], [2, 3], [3, 8], [8, 9], [9, 10, [[10, 11], [11, 12], [12, 10]], [[10, 11], [11, 12], [12, 10]]]]
    ]
# output I want
paths = [
    [[1, 2]],
    [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 4]],
    [[1, 2], [2, 3], [3, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 10]]
    ]
2

There are 2 answers

0
Timeless On BEST ANSWER

IIUC, I visualize it like some sort of a left-join. If so, you can do :

out = []

for path in paths:
    tmp = path[:]
    for edge in path:
        for cycle in cycles:
            if edge[1] == cycle[0][0]:
                tmp.extend(cycle)
    out.append(tmp)

Output :

# [[[1, 2]],
# [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 4]],
# [[1, 2], [2, 3], [3, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 10]]]

Your graph :

enter image description here

0
Riccardo Bucco On

Here is a possible solution:

result = []
for path in paths:
    new_path = []
    for edge_p in path:
        j, i = next(
            ((j, i)
             for j, cycle in enumerate(cycles)
             for i, edge_c in enumerate(cycle)
             if edge_c[0] == edge_p[1]),
            (None, None),
        )
        new_path.append(edge_p)
        if j is not None:
            new_path += cycles[j][i:] + cycles[j][:i]
    result.append(new_path)       

If you try this algorithm with the data you provided you'll get:

>>> result
[[[1, 2]],
 [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 4]],
 [[1, 2], [2, 3], [3, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 10]]]