比较异类列表列表

时间:2018-03-28 00:09:51

标签: python list

比较两个列表很难,关于这个主题有很多帖子。但是,如果我有一个列表列表怎么办?简化为极端:

 members=[['john',1964,'NY'], \
          ['anna',1991,'CA'], \
          ['bert',2001,'AL'], \
          ['eddy',1990,'OH']]

 cash   =[['john',200], \
          ['dirk',200], \
          ['anna',300], \
          ['eddy',150]]

我需要的是差异和交叉点:

 a     =[['john',1964,'NY'], \
         ['anna',1991,'CA'], \
         ['eddy',1990,'OH']]    #BOTH in members and cash

 b     =[['bert',2001,'AL']]    #in members only

通常我用循环来处理这个问题,但我觉得现在是时候切换到更加pythonic的方式了。

最大的问题是我必须在比较它的第一个元素时剔除整个(子)列表。我想象的唯一方法是制作两组名称,比较这些名称并从差异集中重新创建列表(列表)。没比循环好多了。

2 个答案:

答案 0 :(得分:1)

  

通常我用循环来处理它,但我觉得是时候切换到了   一种更加pythonic的方式。

不,我不同意。这个 pythonic,取决于你问的对象。这是你需要做的 -

  1. 生成集
  2. 找到交叉点和差异

  3. 使用第2步中的键构建ab

  4. 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']]
    

答案 1 :(得分:1)

这是一个pandas解决方案,它可以避免显式自己定义循环。如果您希望进行进一步的操作,我只推荐此解决方案。

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