Home > Software engineering >  Merge two Python lists based on a condition and output as a tuple:
Merge two Python lists based on a condition and output as a tuple:

Time:03-11

I have two lists as below:

x = [1, "A", 2, "B", 3, "C", 4, "D"]
y = [1, "Value1", 1, "Value2", 2, "Value3", 3, "Value4", 3, "Value5", 4, "Value6", 4, "Value7"]

The output I want to create is a list of tuples with two values like below :

xy_merge = [("A", "Value1"), ("A", "Value2"),
            ("B", "Value3"),
            ("C", "Value4"), ("C", "Value5"),
            ("D", "Value6"), ("D", "Value7")]

I tried it with many ways by using simple statements and all but could not get the desired output. Please help in getting this output.

CodePudding user response:

Try:

m = dict(zip(x[::2], x[1::2]))
out = [(m[a], b) for a, b in zip(y[::2], y[1::2])]
print(out)

Prints:

[('A', 'Value1'), ('A', 'Value2'), ('B', 'Value3'), ('C', 'Value4'), ('C', 'Value5'), ('D', 'Value6'), ('D', 'Value7')]

CodePudding user response:

x = [1, "A", 2, "B", 3, "C", 4, "D"]
y = [1, "Value1", 1, "Value2", 2, "Value3", 3, "Value4", 3, "Value5", 4, "Value6", 4, "Value7"]

def pairwise(iterable):
    yield from zip(*[iter(iterable)]*2)

to_x = dict(pairwise(x))

xy_merge = [(to_x[key], value) for key, value in pairwise(y)]
print(xy_merge)

Output:

[('A', 'Value1'), ('A', 'Value2'), ('B', 'Value3'), ('C', 'Value4'), ('C', 'Value5'), ('D', 'Value6'), ('D', 'Value7')]
>>> 

pairwise is a generator which, for each iteration, yields the next two items of an iterable. If you iterate pairwise over x, you would get:

(1, 'A'), (2, 'B'), (3, 'C'), (4, 'D')

We can construct a dictionary to_x from these tuples, which maps integers to letters:

to_x = {1: 'A', 2: 'B', 3: 'C', 4: 'D'}

To generate xy_merge, you iterate over y pairwise, and for each iteration, map the integer to a letter in to_x.

CodePudding user response:

Very similar to a previous answer but simpler:

x = [1, "A", 2, "B", 3, "C", 4, "D"]
y = [1, "Value1", 1, "Value2", 2, "Value3", 3, "Value4", 3, "Value5", 4, "Value6", 4, "Value7"]

# yields adjacent pairs from the given list
def getp(lst):
    for i in range(0, len(lst), 2):
        yield lst[i], lst[i 1]
# convert x to a dictionary
dx = {x[i]: x[i 1] for i in range(0, len(x), 2)}
# build list of tuples
yl = [(dx[i], v) for i, v in getp(y)]

print(yl)

Output:

[('A', 'Value1'), ('A', 'Value2'), ('B', 'Value3'), ('C', 'Value4'), ('C', 'Value5'), ('D', 'Value6'), ('D', 'Value7')]

CodePudding user response:

Here is a solution.

import itertools

x = [1, "A", 2, "B", 3, "C", 4, "D"]
y = [1, "Value1", 1, "Value2", 2, "Value3", 3, "Value4", 3, "Value5", 4, "Value6", 4, "Value7"]

keys_x = set([x[2*i] for i in range(len(x) // 2)])
keys_y = set([y[2*i] for i in range(len(y) // 2)])

keys_merge = keys_x.intersection(keys_y)

dict_x = {
    key: [] for key in keys_x
}

for i in range(len(x) // 2):
    dict_x[x[2*i]].append(x[2*i 1])

dict_y = {
    key: [] for key in keys_y
}

for i in range(len(y) // 2):
    dict_y[y[2*i]].append(y[2*i 1])

xy_merge = []

for key in keys_merge:
    xy_merge.extend(
        list(itertools.product(dict_x[key], dict_y[key]))
    )

print(xy_merge)

This prints out:

[('A', 'Value1'), ('A', 'Value2'), ('B', 'Value3'), ('C', 'Value4'), ('C', 'Value5'), ('D', 'Value6'), ('D', 'Value7')]

Notice that if you want to preserve the order, try using list instead of set for keys.

CodePudding user response:

dx, dy = {}, {}

for i in range(0, len(x), 2): dx.setdefault(x[i], []).append(x[i   1])    
for i in range(0, len(y), 2): dy.setdefault(y[i], []).append(y[i   1])

[(vx, vy) for k in dy.keys() for vy in dy[k] for vx in dx[k]]
# [('A', 'Value1'),
#  ('A', 'Value2'),
#  ('B', 'Value3'),
#  ('C', 'Value4'),
#  ('C', 'Value5'),
#  ('D', 'Value6'),
#  ('D', 'Value7')]

CodePudding user response:

so this question has pandas tag it could be like this with pandas:

df_x = pd.DataFrame(zip(x[::2],x[1::2]))
df_y = pd.DataFrame(zip(y[::2],y[1::2]))

df_xy = pd.merge(df_x,df_y, on=0)
xy_merge = df_xy[['1_x','1_y']].apply(tuple, axis=1).tolist()

print(xy_merge)
'''
[('A', 'Value1'),
 ('A', 'Value2'),
 ('B', 'Value3'),
 ('C', 'Value4'),
 ('C', 'Value5'),
 ('D', 'Value6'),
 ('D', 'Value7')]
  • Related