简体   繁体   中英

Python: pair matching elements

I have a the following data structure:

a = [('customerA', '1.0.0'), ('customerB', '1.0.0'), ('customerC', '1.0.1')]
b = (('customerB', '1.1.0'), ('customerC', '1.0.1'))

I want the results to be something like this:

[('customerA', None), ('customerB', '1.0.0', '1.1.0'), ('customerC', '1.0.1', '1.0.1')]

or even skip non existing customers entirely:

[('customerB', '1.0.0', '1.1.0'), ('customerC', '1.0.1', '1.0.1')]

The zip function won't help in this case because b comes from MySQLCursor.fetchall() with WHERE clause for the customer name so it won't match with a if the customer doesn't exist:

>>> [a + (b[1],) for a, b in zip(a, b)]
[('customerA', '1.0.0', '1.1.0'), ('customerB', '1.0.0', '1.0.1')]
>>> import itertools
>>> for a, b in itertools.zip_longest(a, b):
...     print(a, b)
... 
('customerA', '1.0.0') ('customerB', '1.1.0')
('customerB', '1.0.0') ('customerC', '1.0.1')
('customerC', '1.0.1') None

Have you tried to do it directly?

customers_a = dict(a)
result = [(customer, customers_a[customer], version) for customer, version in b if customer in customers_a]

Now, result is exactly

>>> result
[('customerB', '1.0.0', '1.1.0'), ('customerC', '1.0.1', '1.0.1')]

Using collections .

Demo:

import collections
a = [('customerA', '1.0.0'), ('customerB', '1.0.0'), ('customerC', '1.0.1')]
b = (('customerB', '1.1.0'), ('customerC', '1.0.1'))

checkDict = dict(b)
d = collections.defaultdict(list)
for i in (a + list(b)):
    if i[0] in checkDict.keys():
        d[i[0]].append(i[1])
print(d)

Output:

defaultdict(<type 'list'>, {'customerC': ['1.0.1', '1.0.1'], 'customerB': ['1.0.0', '1.1.0']})
In [11]: a = [('customerA', '1.0.0'), ('customerB', '1.0.0'), ('customerC', '1.0.1')]
    ...: b = (('customerB', '1.1.0'), ('customerC', '1.0.1'))

In [12]: ad = dict(a)

In [13]: bd = dict(b)

In [14]: [(k, ad.get(k), bd.get(k)) for k in set(ad.keys()) & set(bd.keys())]
Out[14]: [('customerC', '1.0.1', '1.0.1'), ('customerB', '1.0.0', '1.1.0')]

You could always try itertools.product :

>>> from itertools import product
>>> x = [('customerA', '1.0.0'), ('customerB', '1.0.0'), ('customerC', '1.0.1')]
>>> y = (('customerB', '1.1.0'), ('customerC', '1.0.1'))
>>> [(a, b, d) for (a, b), (c, d) in product(x, y) if a == c]
[('customerB', '1.0.0', '1.1.0'), ('customerC', '1.0.1', '1.0.1')]

Note: This assumes that only only one customer pair exists between the two data structures.

If you want to exclude customers that are only in a you can do it using a list comprehension:

a = [('customerA', '1.0.0'), ('customerB', '1.0.0'), ('customerC', '1.0.1')]
b = (('customerB', '1.1.0'), ('customerC', '1.0.1'))

result = [(ca, x, y) for (ca, x) in a for (cb, y) in b if ca == cb]
# [('customerB', '1.0.0', '1.1.0'), ('customerC', '1.0.1', '1.0.1')]

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