'Merge 2 python 2d lists based on the first element of the second dimension

Pretty simple problem, but no fast solutions coming to mind...

Here are 2 lists ('D2_list0' and 'D2_list1') that I'd like to merge and the result should be 'D2_result'. Do you guys have any ideas how to do that, preferably using numpy?

Indexes [i][0] of both table are timestamps and always ordered

D2_list0 = [[1, 'A', 1], [2, 'B', 4], [3, 'C', 10], [4, 'D', 15], [5, 'E', 20], [6, 'F', 25]]
D2_list1 = [[0, 5], [1, 42], [2, 54], [3, 85], [4, 15], [5, 28]]

#if D2_list0[i][0] matches D2_list0[j][0] then:

D2_result = [[1, 'A', 1, 42], [2, 'B', 4, 54], [3, 'C', 10, 85], [4, 'D', 15, 15], [5, 'E', 20, 28]]

My current solution but not optimized:

def unifaction(table1, table2):
    unified_table = []

    if table1[0][0] > table2[0][0]:
        table1_counter = 0
        for i in range(0, len(table2)):
            if table1[table1_counter][0] == table2[i][0]:
                table2[i].pop(0)

                for value in table2[i]:
                    table1[table1_counter].append(value)

                unified_table.append(table1[table1_counter])

                if (table1_counter + 1) < len(table1):
                    table1_counter = table1_counter + 1
                else:
                    break

    elif table2[0][0] > table1[0][0]:
        table2_counter = 0
        for i in range(0, len(table1)):
            if table1[i][0] == table2[table2_counter][0]:
                table2[table2_counter].pop(0)

                for value in table2[table2_counter]:
                    table1[i].append(value)
                unified_table.append(table1[i])

                if (table2_counter + 1) < len(table2):
                    table2_counter = table2_counter + 1
                else:
                    break


    return unified_table


Solution 1:[1]

This could be a good use case for pandas:

import pandas as pd

D2_list0 = [[1, 'A'], [2, 'B'], [3, 'C'], [4, 'D'], [5, 'E'], [6, 'F']]
D2_list1 = [[0, 5], [1, 42], [2, 54], [3, 85], [4, 15], [5, 28]]

s1 = pd.DataFrame(D2_list0).set_index(0)[1]
s2 = pd.DataFrame(D2_list1).set_index(0)[1]
df = pd.DataFrame({
    "one": s1,
    "two": s2,
}).dropna()

D2_result = [[1, 'A', 42], [2, 'B', 54], [3, 'C', 85], [4, 'D', 15], [5, 'E', 28]]

assert df.reset_index().values.tolist() == D2_result

Solution 2:[2]

D2_result = D2_list0.copy()
for i in range(len(D2_list0)):
    for j in range(len(D2_list1)):
        if D2_list0[i][0] == D2_list1[j][0]:
            D2_result[i].append(D2_list1[j][1])

For every element of D2_list0 I iterate over all elements of D2_list1 and collect all of the matching values. Complexity of O(n^2)

Edit: when the first value is sorted and unique:

D2_result = D2_list0.copy()
j = 0
for i in range(len(D2_list0)):
    while j < len(D2_list0) and D2_list0[i][0] != D2_list1[j][0]:
        j += 1
    if j >= len(D2_list0):
        break
    D2_result[i].append(D2_list1[j][1])

Complexity of O(n)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 hilberts_drinking_problem
Solution 2