Reputation: 216
Comparing two lists is tough, there are numerous posts on this subject. But what if I have a list of lists? Simplified to extreme:
members=[['john',1964,'NY'], \
['anna',1991,'CA'], \
['bert',2001,'AL'], \
['eddy',1990,'OH']]
cash =[['john',200], \
['dirk',200], \
['anna',300], \
['eddy',150]]
What I need are differences and intersections:
a =[['john',1964,'NY'], \
['anna',1991,'CA'], \
['eddy',1990,'OH']] #BOTH in members and cash
b =[['bert',2001,'AL']] #in members only
Usually I handle this with a loop, but I feel it is time to switch to a more pythonic way.
The big problem is that I have to fish out the whole (sub)list while comparing just it's first element. The only way I imagine is to make two sets of names, compare these and recreate the lists (of lists) from the sets of differences. Not much better than a loop.
Upvotes: 1
Views: 92
Reputation: 164823
Here is a pandas
solution, which avoids having to explicitly define loops yourself. I only recommend this solution if you are looking to perform further manipulations.
import pandas as pd
members = [['john',1964,'NY'],
['anna',1991,'CA'],
['bert',2001,'AL'],
['eddy',1990,'OH']]
cash = [['john',200],
['dirk',200],
['anna',300],
['eddy',150]]
df_members = pd.DataFrame(members, columns=['name', 'year', 'state'])
df_cash = pd.DataFrame(cash, columns=['name', 'value'])
mask = df_members['name'].isin(set(df_cash['name']))
members_common = df_members[mask].values.tolist()
members_membersonly = df_members[~mask].values.tolist()
# members_common
# [['john', 1964, 'NY'], ['anna', 1991, 'CA'], ['eddy', 1990, 'OH']]
# members_membersonly
# [['bert', 2001, 'AL']]
Upvotes: 1
Reputation: 403128
Usually I handle this with a loop, but I feel it is time to switch to a more pythonic way.
Nah, I disagree. This is pythonic, depending on who you ask. Here's what you'd need to do -
Find the intersection and difference
Use the keys from step 2 to build a
and b
members_set = {m[0] for m in members}
cash_set = {c[0] for c in cash}
inter = members_set & cash_set
diff = members_set - cash_set
a = [m for m in members if m[0] in inter]
b = [m for m in members if m[0] in diff]
print(a)
[['john', 1964, 'NY'], ['anna', 1991, 'CA'], ['eddy', 1990, 'OH']]
print(b)
[['bert', 2001, 'AL']]
Upvotes: 1