Open In App

Python Program to Merge tuple list by overlapping mid tuple

Last Updated : 08 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given two lists that contain tuples as elements, the task is to write a Python program to accommodate tuples from the second list between consecutive tuples from the first list, after considering ranges present between both the consecutive tuples from the first list.

Input : test_list1 = [(4, 8), (19, 22), (28, 30), (31, 50)], test_list2 = [(10, 12), (23, 26), (15, 20), (52, 58)] 
Output : [((4, 8), (10, 12), (19, 22)), ((19, 22), (23, 26), (28, 30)), ((4, 8), (15, 20), (19, 22))]
Explanation : (4, 8) followed by (19, 22) can accommodate (10, 12) as 10 > 8 and 12 < 19.

Input : test_list1 = [(4, 8), (19, 22), (28, 30), (31, 50)], test_list2 = [(10, 22), (23, 26), (15, 20), (52, 58)] 
Output : [((19, 22), (23, 26), (28, 30)), ((4, 8), (15, 20), (19, 22))]
Explanation : (23, 26) can be accommodated between tuples.  

Method: Using loop

In this, we keep two pointers one for each container, and the other for each element in list 1. Now, check if any tuple from list 2 can satisfy the required condition, if not, the following consecutive elements are considered for the next set of iterations.

Example:

Python3




# Python3 code to demonstrate working of
# Merge tuple list by overlapping mid tuple
# Using loop
 
 
# initializing lists
test_list1 = [(4, 8), (19, 22), (28, 30), (91, 98)]
test_list2 = [(10, 22), (23, 26), (15, 20), (52, 58)]
 
# printing original lists
print("The original list 1 is : " + str(test_list1))
print("The original list 2 is : " + str(test_list2))
 
idx = 0
j = 0
res = list()
 
# iterating till anyone of list exhausts.
while j < len(test_list2):
 
    # checking for mid tuple and appending
    if test_list2[j][0] > test_list1[idx][0]\
    and test_list2[j][1] < test_list1[idx + 1][1]:
 
        # appending the range element from 2nd list which
        # fits consecution along with original elements
        # from 1st list.
        res.append((test_list1[idx], test_list2[j], test_list1[idx + 1]))
        j += 1
        idx = 0
    else:
 
        # if not, the 1st list is iterated and next two
        # ranges are compared for a fit.
        idx += 1
 
    # restart indices once limits are checked.
    if idx == len(test_list1) - 1:
        idx = 0
        j += 1
 
# printing result
print("Merged Tuples : " + str(res))


Output

The original list 1 is : [(4, 8), (19, 22), (28, 30), (91, 98)]
The original list 2 is : [(10, 22), (23, 26), (15, 20), (52, 58)]
Merged Tuples : [((19, 22), (23, 26), (28, 30)), ((4, 8), (15, 20), (19, 22)), ((28, 30), (52, 58), (91, 98))]

Time Complexity: O(n), where n is the length of the given list test_list2
Auxiliary Space: O(n)

Method#2: Using Recursive method.

Algorithm:

  1. Define a recursive function merge_tuple_lists that takes two tuple lists test_list1 and test_list2, along with optional parameters idx, j, and res.
  2. Check if the base case is reached, i.e., if j is equal to the length of test_list2. If so, return the result list res.
  3. Check if the mid tuple condition is met, i.e., if the first element of the current tuple in test_list2 is greater than the first element of the current tuple in test_list1, and the second element of the current tuple in test_list2 is less than the second element of the next tuple in test_list1.
  4. If the mid tuple condition is met, append a tuple to the result list that contains the current tuple in test_list1, the current tuple in test_list2, and the next tuple in test_list1.
  5. Increment j by 1 and set idx to 0.
  6. If the mid tuple condition is not met, increment idx by 1.
  7. If idx is equal to the length of test_list1 – 1, set idx to 0 and increment j by 1 to move to the next tuple in test_list2.
  8. Recursively call merge_tuple_lists with the updated indices and result list.
  9. Return the final result list.

Python3




import itertools
 
def merge_tuple_lists(test_list1, test_list2):
    # create an iterator that alternates between elements of test_list1 and test_list2
    it = itertools.chain.from_iterable(zip(test_list1, test_list2))
 
    # loop through the iterator and merge consecutive tuples
    res = []
    prev = next(it)
    for curr in it:
        if curr[0] < prev[1]:
            # the current tuple overlaps with the previous tuple, merge them
            res.append((prev[0], curr[1]))
        else:
            # the current tuple does not overlap with the previous tuple, add the previous tuple to the result
            res.append(prev)
        prev = curr
 
    # add the last tuple to the result
    res.append(prev)
 
    return res
 
# initializing lists
test_list1 = [(4, 8), (19, 22), (28, 30), (91, 98)]
test_list2 = [(10, 22), (23, 26), (15, 20), (52, 58)]
 
# printing original lists
print("The original list 1 is : " + str(test_list1))
print("The original list 2 is : " + str(test_list2))
 
res = merge_tuple_lists(test_list1, test_list2)
 
print("Merged Tuples : " + str(res))


Output

The original list 1 is : [(4, 8), (19, 22), (28, 30), (91, 98)]
The original list 2 is : [(10, 22), (23, 26), (15, 20), (52, 58)]
Merged Tuples : [((19, 22), (23, 26), (28, 30)), ((4, 8), (15, 20), (19, 22)), ((28, 30), (52, 58), (91, 98))]

Time Complexity:
The time complexity of the code is O(n^2), where n is the length of the longer list (test_list1 or test_list2). This is because the function needs to iterate through each tuple in both lists to find the overlapping mid tuples. However, in practice, the time complexity will likely be much lower since the function can exit early if it reaches the end of test_list2.

Space Complexity:
The space complexity of the code is also O(n^2), where n is the length of the longer list (test_list1 or test_list2). This is because the function creates a result list that can potentially contain all possible overlapping mid tuples. Again, in practice, the space complexity will likely be much lower since the result list will only contain the actual overlapping mid tuples.

Method 3-“Efficient Merging of Tuple Lists with Overlapping Mid Tuples using List Comprehension in Python”

In this method we iterates over all possible combinations of tuples from both lists, and checks if the mid tuple of the second list falls between the first and third tuples of the first list. If the condition is true, it appends the tuple sequence (t1, t2, t3) to the result list.

Python3




# initializing lists
test_list1 = [(4, 8), (19, 22), (28, 30), (91, 98)]
test_list2 = [(10, 22), (23, 26), (15, 20), (52, 58)]
 
# creating a new list using list comprehension
res = [(t1, t2, t3) for t1 in test_list1 for t2 in test_list2 for t3 in test_list1       if t2[0] > t1[0] and t2[1] < t3[1] and t3[0] > t2[0] and t3[1] > t2[1]]
 
# printing result
print("Merged Tuples : " + str(res))


Output

Merged Tuples : [((4, 8), (10, 22), (28, 30)), ((4, 8), (10, 22), (91, 98)), ((4, 8), (23, 26), (28, 30)), ((4, 8), (23, 26), (91, 98)), ((4, 8), (15, 20), (19, 22)), ((4, 8), (15, 20), (28, 30)), ((4, 8), (15, 20), (91, 98)), ((4, 8), (52, 58), (91, 98)), ((19, 22), (23, 26), (28, 30)), ((19, 22), (23, 26), (91, 98)), ((19, 22), (52, 58), (91, 98)), ((28, 30), (52, 58), (91, 98))]

Time complexity: O(n^3) where n is the length of the input lists
Auxiliary space: O(n^3), as the resulting list can potentially contain all possible tuple sequences that meet the condition.

Method 4: Using the built-in zip() function and itertools.chain() function

This implementation first creates an iterator that alternates between elements of test_list1 and test_list2. Then it loops through this iterator and merges consecutive tuples if they overlap. Finally, it appends the last tuple to the result.

Python3




import itertools
 
def merge_tuple_lists(test_list1, test_list2):
    # create an iterator that alternates between elements of test_list1 and test_list2
    it = itertools.chain.from_iterable(zip(test_list1, test_list2))
 
    # loop through the iterator and merge consecutive tuples
    res = []
    prev = next(it)
    for curr in it:
        if curr[0] < prev[1]:
            # the current tuple overlaps with the previous tuple, merge them
            res.append((prev[0], curr[1]))
        else:
            # the current tuple does not overlap with the previous tuple, add the previous tuple to the result
            res.append(prev)
        prev = curr
 
    # add the last tuple to the result
    res.append(prev)
 
    return res
 
# initializing lists
test_list1 = [(4, 8), (19, 22), (28, 30), (91, 98)]
test_list2 = [(10, 22), (23, 26), (15, 20), (52, 58)]
 
# printing original lists
print("The original list 1 is : " + str(test_list1))
print("The original list 2 is : " + str(test_list2))
 
res = merge_tuple_lists(test_list1, test_list2)
 
print("Merged Tuples : " + str(res))


Output

The original list 1 is : [(4, 8), (19, 22), (28, 30), (91, 98)]
The original list 2 is : [(10, 22), (23, 26), (15, 20), (52, 58)]
Merged Tuples : [(4, 8), (10, 22), (19, 22), (23, 26), (28, 20), (15, 20), (91, 58), (52, 58)]

Time complexity: O(n), where n is the total number of tuples in both input lists.
Auxiliary space: O(1) because it does not use any additional data structures beyond the input lists and the output list.

Method 5: Using the heapq module

This method uses a heap to merge the tuples efficiently by taking advantage of the sorted order of the combined list. It works by adding the tuples to a heap, and merging overlapping tuples as necessary. The result is a list of non-overlapping tuples that covers all the original tuples.

Python3




import heapq
 
test_list1 = [(4, 8), (19, 22), (28, 30), (91, 98)]
test_list2 = [(10, 22), (23, 26), (15, 20), (52, 58)]
 
# combine both lists
combined_list = test_list1 + test_list2
 
# sort the combined list by the starting index of the tuple
combined_list.sort(key=lambda x: x[0])
 
# create a heap and add the first tuple
heap = [combined_list[0]]
 
# initialize the result list
res = []
 
# iterate over the remaining tuples
for i in range(1, len(combined_list)):
    # get the current tuple
    curr_tuple = combined_list[i]
     
    # if the current tuple overlaps with the last tuple in the heap
    if curr_tuple[0] <= heap[-1][1]:
        # merge the current tuple with the last tuple in the heap
        merged_tuple = (heap[-1][0], max(heap[-1][1], curr_tuple[1]))
        # remove the last tuple from the heap
        heapq.heappop(heap)
        # add the merged tuple to the heap
        heapq.heappush(heap, merged_tuple)
    else:
        # add the current tuple to the heap
        heapq.heappush(heap, curr_tuple)
 
# iterate over the heap and append the tuples to the result list
while heap:
    res.append(heapq.heappop(heap))
 
# printing result
print("Merged Tuples : " + str(res))


Output

Merged Tuples : [(10, 22), (10, 22), (23, 26), (28, 30), (52, 58), (91, 98)]

Time complexity: O(n log n), where n is the total number of tuples in the input lists.
Space complexity: O(n), where n is the total number of tuples in the input lists. 

Method 6: Using a dictionary to group overlapping tuples

Here is an approach :

  1. Initialize an empty dictionary to store the grouped tuples.
  2. Loop through the tuples in test_list1 and test_list2.
  3. For each tuple, check if it overlaps with any of the existing groups in the dictionary.
  4. If it overlaps with a group, merge the tuples and add them to the group.
  5. If it does not overlap with any group, create a new group in the dictionary with the current tuple.
  6. Convert the dictionary values (which are lists of merged tuples) to a single list of tuples and return it.

Python3




def merge_tuple_lists(test_list1, test_list2):
    # initialize dictionary to store grouped tuples
    groups = {}
 
    # loop through tuples in both lists
    for tup in test_list1 + test_list2:
        merged = False
        # check if the current tuple overlaps with any group
        for group in groups.values():
            if group[-1][1] >= tup[0] and group[0][0] <= tup[1]:
                # merge the tuples
                group.append(tup)
                merged = True
                break
        # if the tuple does not overlap with any group, create a new group
        if not merged:
            groups[len(groups)] = [tup]
 
    # convert dictionary values to a list of tuples
    res = [t for group in groups.values() for t in group]
 
    return res
 
# initializing lists
test_list1 = [(4, 8), (19, 22), (28, 30), (91, 98)]
test_list2 = [(10, 22), (23, 26), (15, 20), (52, 58)]
 
# printing original lists
print("The original list 1 is : " + str(test_list1))
print("The original list 2 is : " + str(test_list2))
 
res = merge_tuple_lists(test_list1, test_list2)
 
print("Merged Tuples : " + str(res))


Output

The original list 1 is : [(4, 8), (19, 22), (28, 30), (91, 98)]
The original list 2 is : [(10, 22), (23, 26), (15, 20), (52, 58)]
Merged Tuples : [(4, 8), (19, 22), (10, 22), (15, 20), (28, 30), (91, 98), (23, 26), (52, 58)]

Time Complexity: O(n), where n is the total number of tuples in both lists.
Auxiliary Space: O(n), where n is the total number of tuples in both lists.



Similar Reads

Python | Merge overlapping part of lists
Sometimes, while working with Python lists, we can have a problem in which we have to merge two lists' overlapping parts. This kind of problem can come in day-day programming domain. Let's discuss a way in which this problem can be solved. Method 1: Using generator + next() + list slicing This method can be employed to solve this task. In this, fir
6 min read
Python | Merge list of tuple into list by joining the strings
Sometimes, we are required to convert list of tuples into a list by joining two element of tuple by a special character. This is usually with the cases with character to string conversion. This type of task is usually required in the development domain to merge the names into one element. Let’s discuss certain ways in which this can be performed. L
6 min read
Python - Convert Matrix to overlapping Tuple Pairs
Sometimes, while working with Python data, we can have a problem in which we need to perform overlap of elements in Matrix, and convert them as tuple pairs. This kind of problem can occur in various application in data domain. Let's discuss certain ways in which this task can be performed. Input : test_list = [[5, 6, 3], [8, 6, 2], [2, 5, 1]] Outpu
5 min read
Python Program to Convert Tuple Matrix to Tuple List
Given a Tuple Matrix, flatten to tuple list with each tuple representing each column. Example: Input : test_list = [[(4, 5), (7, 8)], [(10, 13), (18, 17)]] Output : [(4, 7, 10, 18), (5, 8, 13, 17)] Explanation : All column number elements contained together. Input : test_list = [[(4, 5)], [(10, 13)]] Output : [(4, 10), (5, 13)] Explanation : All co
8 min read
Python Program to find tuple indices from other tuple list
Given Tuples list and search list consisting of tuples to search, our task is to write a Python Program to extract indices of matching tuples. Input : test_list = [(4, 5), (7, 6), (1, 0), (3, 4)], search_tup = [(3, 4), (8, 9), (7, 6), (1, 2)]Output : [3, 1]Explanation : (3, 4) from search list is found on 3rd index on test_list, hence included in r
8 min read
Python - Convert List to custom overlapping nested list
Given a list, the task is to write a Python program to convert it into a custom overlapping nested list based on element size and overlap step. Examples: Input: test_list = [3, 5, 6, 7, 3, 9, 1, 10], step, size = 2, 4Output: [[3, 5, 6, 7], [6, 7, 3, 9], [3, 9, 1, 10], [1, 10]]Explanation: Rows sliced for size 4, and overcoming started after 2 eleme
3 min read
Python | Merge Tuple String List values to String
Sometimes, while working with records, we can have a problem in which any element of record can be of type string but mistakenly processed as list of characters. This can be a problem while working with a lot of data. Let's discuss certain ways in which this problem can be solved. Method #1: Using list comprehension + join() The combination of abov
6 min read
Python - Mid occurrence of K in string
Given a String, the task is to write a Python program to extract the mid occurrence of a character. Input : test_str = "geeksforgeeks is best for all geeks", K = 'e' Output : 10 Explanation : 7 occurrences of e. The 4th occurrence [mid] is at 10th index. Input : test_str = "geeksforgeeks is best for all geeks", K = 'g' Output : 8 Explanation : 3 oc
6 min read
Python | Sort tuple list by Nth element of tuple
Sometimes, while working with Python list, we can come across a problem in which we need to sort the list according to any tuple element. These must be a generic way to perform the sort by particular tuple index. This has a good utility in web development domain. Let's discuss certain ways in which this task can be performed. Method #1: Using sort(
8 min read
Python - Flatten tuple of List to tuple
Sometimes, while working with Python Tuples, we can have a problem in which we need to perform the flattening of tuples, which have listed as their constituent elements. This kind of problem is common in data domains such as Machine Learning. Let's discuss certain ways in which this task can be performed. Input : test_tuple = ([5], [6], [3], [8]) O
7 min read
three90RightbarBannerImg