Nobi
Nobi

Reputation: 1109

Compare flat list and nested list

I want to compare the two lists below. edges is a list of tuples while b_edge is a nested list of tuples. what i want is to append edges[i][2] to all b_edge[i][j] if b_edge[i][j] == edge[0:2].

Here are the lists:

edges = [('1.0', '2.0',{'length':0.35}),('2.0', '3.0',{'length':0.46,}),('3.0', '4.0', {'length':0.49}),(4.0, 5.0,{'length':0.22}),('5.0', '6.0',{'length':0.54}),('6.0', '7.0', {'length':0.49}),('7.0', '8.0',{'length':0.22}),(5.0, 6.0,{'length':0.54})]

b_edge = [[('1.0', '2.0'), ('2.0', '3.0'), ('3.0', '4.0')], [('5.0', '6.0'), ('6.0', '7.0'), ('7.0', '8.0')]]

Desired output:

[[('1.0', '2.0', {'length': 0.35}), ('2.0', '3.0', {'length': 0.46}), ('3.0', '4.0', {'length': 0.49})], [('5.0', '6.0', {'length': 0.35}), ('6.0', '7.0', {'length': 0.46}), ('7.0', '8.0', {'length': 0.49})]

I tried this:

result = []
for j in b_edge:
    temp = []
    for l,k in enumerate(j):
        if j[l][0:2] == edges[l][:2]:
            temp.append(k + (edges[l][2],))
    result.append(temp)
print 'result', result

and have also checked these answers on SO compare two lists and print out unequal elements and similar question but they dont quite match what I want.

and got this result:

[[('1.0', '2.0', {'length': 0.35}), ('2.0', '3.0', {'length': 0.46}), ('3.0', '4.0', {'length': 0.49})], []]

It seems to append the dictionary only to the first element in the nested list for the second it just outputs an empty list.

Thank you.

Upvotes: 1

Views: 163

Answers (3)

Pokey McPokerson
Pokey McPokerson

Reputation: 762

One liner of glory:

result = [[edge for edge in edges if (edge[0], edge[1]) in edge_group] for edge_group in b_edge]

The word edge feels weird in my mouth now.

Also, I know you said that the data is how you get it, but I would personally still change it to a dictionary like so:

edge_lengths = {(edge[0], edge[1]): edge[2]['length'] for edge in edges}
# Gives you:
# {('1.0', '2.0'): 0.35, ('3.0', '4.0'): 0.49, ... , ('5.0', '6.0'): 0.54}

# Get lengths
print [[edge_lengths[edge] for edge in edge_group] for edge_group in b_edge]
# [[0.35, 0.46, 0.49], [0.54, 0.49, 0.22]]

Of course it's up to you :)

Upvotes: 2

Alex P. Miller
Alex P. Miller

Reputation: 2246

Try this:

result = b_edge
tmp_dict = { (i[0],i[1]): i[2] for i in edges }
for index_j, j in enumerate(b_edge):
    for index_i, i in enumerate(j):
        if i in tmp_dict:
            result[index_j][index_i] = result[index_j][index_i] + (tmp_dict[i],)

I created a dictionary to map your tuples to your {"length"} dictionary and used that to produce your desired output.

Upvotes: 2

timgeb
timgeb

Reputation: 78700

I would create a mapping of number-tuples to the length like this:

>>> num_to_len = {x[0:2]:x[2] for x in edges}
>>> num_to_len
{(4.0, 5.0): {'length': 0.22}, ('3.0', '4.0'): {'length': 0.49}, (5.0, 6.0): {'length': 0.54}, ('1.0', '2.0'): {'length': 0.35}, ('6.0', '7.0'): {'length': 0.49}, ('2.0', '3.0'): {'length': 0.46}, ('7.0', '8.0'): {'length': 0.22}, ('5.0', '6.0'): {'length': 0.54}}

Then build your desired result like this:

>>> [[x if x not in num_to_len else x+(num_to_len[x],) for x in b_edge[0]]]
[[('1.0', '2.0', {'length': 0.35}), ('2.0', '3.0', {'length': 0.46}), ('3.0', '4.0', {'length': 0.49})]]

Note that wrapping everything in another list, as you specified, is probably not neccesary. So unless you have a good reason, skip the outermost brackets in the list comprehension.

Upvotes: 1

Related Questions