简体   繁体   中英

List of tuples from (a, all b) to (b, all a)

I am starting with a list of tuples (a,all b). I want to end with a list of tuples (b,all a).

For example:

FROM  
(a1,[b1,b2,b3])  
(a2,[b2])  
(a3,[b1,b2])

TO  
(b1,[a1,a3])  
(b2[a1,a2,a3])  
(b3,[a1]

How do I do this using Python 2? Thank you for your help.

You can use collections.defaultdict :

tups = [
    ('a1',['b1','b2','b3']),
    ('a2',['b2']),
    ('a3',['b1','b2'])
]

d = collections.defaultdict(list)
for a, bs in tups:
    for b in bs:
        d[b].append(a)

Then:

>>> d.items()
[('b1', ['a1', 'a3']), ('b2', ['a1', 'a2', 'a3']), ('b3', ['a1'])]

I would do something like

from collections import defaultdict

output = defaultdict(list)

for a, b_s in input:
    for b in b_s:
        output[b].append(a)

# to put back to tuples:

output = tuple(output.items())

A sorting version, for fun:

import itertools
import operator

# Function to get first element of a tuple
fst = operator.itemgetter(0)


def invert(items):
    # (b, a) pairs, sorted by b
    pairs = sorted((b, a) for a, bs in items for b in bs)

    # (b, [(b, a)]) groups
    groups = itertools.groupby(pairs, key=fst)

    # (b, [a]) groups
    return [(b, [a for (_, a) in items]) for b, items in groups]


print(invert([
    ('a1', ['b1', 'b2', 'b3']),
    ('a2', ['b2']),
    ('a3', ['b1', 'b2']),
]))

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