Bryce
Bryce

Reputation: 21

Use the values of one list to group a second list

Say I have data like this:

Owners = ('Bob', 'Bob', 'Bob', 'Jeff', 'Jeff', 'Mary', 'Ana')
Pets = ('Snake', 'Bird', 'Cat', 'Dog', 'Cat', 'Bird', 'Cat')

Each name corresponds to the animal(s) they own. I want to create a list of lists based on the owner:

PetsByOwner = [(Snake, Bird, Cat), (Dog, Cat), (Bird), (Cat)]


PetsByOwner= []
for i in Owners:
    if PetsByOwner and PetsByOwner[-1][0] == i:
        PetsByOwner[-1].append(value)
    else:
        PetsByValue.append([value])

I tried this, but it would only break up the owners, not the pets. How do I connect a second list? Any help would be appreciated.

Upvotes: 2

Views: 46

Answers (2)

Andrej Kesely
Andrej Kesely

Reputation: 195438

You can use groupby from itertools:

from itertools import groupby

Owners = ('Bob', 'Bob', 'Bob', 'Jeff', 'Jeff', 'Mary', 'Ana')
Pets = ('Snake', 'Bird', 'Cat', 'Dog', 'Cat', 'Bird', 'Cat')

print([tuple(v) for g, v in groupby(Pets, key=lambda v, c=iter(Owners): next(c))])

Output:

[('Snake', 'Bird', 'Cat'), ('Dog', 'Cat'), ('Bird',), ('Cat',)]

And if you want to add Owner to the result

print({g: tuple(v) for g, v in groupby(Pets, key=lambda v, c=iter(Owners): next(c))})

Prints:

{'Bob': ('Snake', 'Bird', 'Cat'), 'Jeff': ('Dog', 'Cat'), 'Mary': ('Bird',), 'Ana': ('Cat',)}

Upvotes: 1

Ajax1234
Ajax1234

Reputation: 71451

You can use collections.defaultdict:

import collections
Owners = ('Bob', 'Bob', 'Bob', 'Jeff', 'Jeff', 'Mary', 'Ana')
Pets = ('Snake', 'Bird', 'Cat', 'Dog', 'Cat', 'Bird', 'Cat')
d = collections.defaultdict(list)
for a, b in zip(Owners, Pets):
  d[a].append(b)
final_result = {a:tuple(b) for a, b in d.items()}

Output:

{'Bob': ('Snake', 'Bird', 'Cat'), 'Jeff': ('Dog', 'Cat'), 'Mary': ('Bird',), 'Ana': ('Cat',)}

Upvotes: 1

Related Questions