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')]