简体   繁体   中英

Merge two list of tuples based on overlapp python

Given two lists x, y such that they both have been initialized as shown below:

x = [(0, 3), (5, 8), (16, 19), (21, 24), (28, 30), (40, 42), (46, 47), (50, 54), (58, 63), (69, 71)]
y = [(9, 10), (26, 27), (29, 31), (35, 36), (41, 43), (48, 49), (66, 67), (70, 72), (77, 78), (85, 86)]

I want to form a new list of tuples where each tuple has contiguous tuples from x and an overlapping tuple from y.

For the example above, the output would be:

[((5, 8) (9, 10) (16, 19)), ((21, 24) (26, 27) (28, 30)), ((28, 30) (29, 31) (40, 42)), ((28, 30) (35, 36) (40, 42)), ((40, 42) (41, 43) (46, 47)), ((46, 47) (48, 49) (50, 54)),((58, 63) (66, 67) (69, 71))]

My code:

lst = []
for i in range(len(x)):
  if i+1 < len(x):
    context = x[i],x[i+1]
    for j in y:
      if j[0] >= context[0][0] and j[0] <= context[1][0]:
        lst.append((context[0],j,context[1]))
        

I need better and efficient ways to write this code.

You can use two variables to keep track of indices in x and y list. Using the conditions specified in the problem, these indices can be incremented whenever the given condition has been satisfied. At every iteration, the algorithm checks if x[i][0] < y[j][0] and x[i+1][1] > y[j][1] ( The upper and lower bound provided by the contigous tuples in x . If this condition is true, we increment j (y-index) so that we can check if the next element lies in the given range. Else, we increment i (x-index) and repeat the process.

x = [(0, 3), (5, 8), (16, 19), (21, 24), (28, 30), (40, 42), (46, 47), (50, 54), (58, 63), (69, 71)]
y = [(9, 10), (26, 27), (29, 31), (35, 36), (41, 43), (48, 49), (66, 67), (70, 72), (77, 78), (85, 86)]

i = 0
j = 0
result = list()

while i < len(x) - 1 and j < len(y):
    if y[j][0] > x[i][0] and y[j][1] < x[i + 1][1]:
        result.append((x[i], y[j], x[i + 1]))
        j += 1
    else:
        i += 1
print(result)

Output -

[((5, 8), (9, 10), (16, 19)),
 ((21, 24), (26, 27), (28, 30)),
 ((28, 30), (29, 31), (40, 42)),
 ((28, 30), (35, 36), (40, 42)),
 ((40, 42), (41, 43), (46, 47)),
 ((46, 47), (48, 49), (50, 54)),
 ((58, 63), (66, 67), (69, 71))]

You can use Python Sorting

from operator import itemgetter, attrgetter
output = sorted((x + y), key=itemgetter(0))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM