Python 仅比较字典列表中的某些字典键值

Python 仅比较字典列表中的某些字典键值,python,list,dictionary,search,set,Python,List,Dictionary,Search,Set,我有300k+个API调用字典,其格式如下:(1个API调用将返回1个dict,因此以下每个dict都是成功的连续API调用的结果,在每次API调用之后,代码需要在返回的dict上运行) 我必须将上述单个词典附加到词典列表中,并满足以下条件: 首选dwg、pdf、bmp“类型” docx、pptx、xlsx为非首选格式,仅在不存在上述任何格式时才予以考虑 (N.)name、batch、Sem、(Sub)subject、files、size可以是任何值,相同['N'、'batch'、'Sem'、'

我有300k+个API调用字典,其格式如下:(1个API调用将返回1个dict,因此以下每个dict都是成功的连续API调用的结果,在每次API调用之后,代码需要在返回的dict上运行)

我必须将上述单个词典附加到词典列表中,并满足以下条件:

  • 首选dwg、pdf、bmp“类型”
  • docx、pptx、xlsx为非首选格式,仅在不存在上述任何格式时才予以考虑
  • (N.)name、batch、Sem、(Sub)subject、files、size可以是任何值,相同['N'、'batch'、'Sem'、'Sub']集的所有dict在各自的API调用中依次返回
  • uid是每个词典的唯一编号。从未重复过
  • 条目是相同的集合。因此,如果最终列表中已经有任何条目,则以非首选“类型”作为值的单个dict不应进入最终列表(例如,如果已经存在具有docx/dwg/pdf/bmp的条目,则pptx不应进入最终列表)
  • 首选和非首选之间的“类型”中没有层次结构。例如:如果存在一个带有pptx的条目,则另一个带有docx的条目不应出现
  • 初始列表为空
  • 因此,在上述数据中,只有以下数据应进入最终列表:

    [{'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAD', 'Files': 21, 'Type': 'dwg', 'Size(MB)': 98, 'uid': 732854},
    {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAD', 'Files': 8, 'Type': 'pdf', 'Size(MB)': 42, 'uid': 735554},
    {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAM', 'Files': 8, 'Type': 'dwg', 'Size(MB)': 71, 'uid': 737328},
    {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'MIM', 'Files': 8, 'Type': 'pptx', 'Size(MB)': 28, 'uid': 687281},
    {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'MET', 'Files': 20, 'Type': 'pptx', 'Size(MB)': 204, 'uid': 457281},
    ...]
    
    我尝试使用的代码:

    list = []
    dict = {'N.': name, 'Batch': year, 'Sem': semester, 'Sub': subject, 'Files': nofiles, 'Type': format, 'Size(MB)': size, 'uid': uniqueid}
    comparekeys = ['N.','Batch','Sem','Sub']
    nptype = ['docx', 'pptx', 'xlsx']
    if dict not in list and format in nptype:
       for key in comparekeys:
          if dict[key] == (item[key] for item in list):
             break
    list.append(dict)
    

    上述代码还附加了非首选格式,如果列表中已存在条目,则无法查找。我也试过使用zip()、set()、.keys(),但无法制定正确的代码。

    您说过,在API调用中,相同['N'、'Batch'、'Sem'、'Sub']集的所有dict都会一个接一个地返回。所以我假设它们是组合在一起的

    使用
    itertools.groupby()
    处理每组DICT。对于每个组,对其进行排序,使首选类型优先于非首选类型。然后,第一个排序的dict总是添加到结果中,因为它要么是首选类型,要么没有任何首选类型。在其余排序的dict中,只有那些具有首选类型的dict被追加到结果中

    import itertools as it
    
    data = [
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAD', 'Files': 21, 'Type': 'dwg', 'Size(MB)': 98, 'uid': 732854},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAD', 'Files': 8, 'Type': 'pdf', 'Size(MB)': 42, 'uid': 735554},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAD', 'Files': 16, 'Type': 'docx', 'Size(MB)': 104, 'uid': 746748},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAD', 'Files': 8, 'Type': 'pptx', 'Size(MB)': 57, 'uid': 731024},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAM', 'Files': 8, 'Type': 'dwg', 'Size(MB)': 71, 'uid': 737328},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAM', 'Files': 8, 'Type': 'docx', 'Size(MB)': 22, 'uid': 376494},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'MIM', 'Files': 8, 'Type': 'pptx', 'Size(MB)': 28, 'uid': 687281},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'MIM', 'Files': 8, 'Type': 'docx', 'Size(MB)': 20, 'uid': 687231},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'MET', 'Files': 20, 'Type': 'pptx', 'Size(MB)': 204, 'uid': 457281},
    ]
    
    preferred_types = ('dwg', 'pdf', 'bmp')
    
    result = []
    
    key = lambda v:(v['N.'], v['Batch'], v['Sem'], v['Sub'])
    
    for _, values in it.groupby(data, key=key):
        values = sorted(values, key=lambda v:v['Type'] not in preferred_types)
        
        result.append(values[0])
        
        result.extend(value for value in values[1:] if value['Type'] in preferred_types)
                
    for row in result:
        print(row)
    

    我猜您在开始时就错过了要点:1个API调用返回1个dict。但是,连续的API调用依次返回集合['N'、'Batch'、'Sem'、'Sub']的所有可能排列。要添加,任何固定集合最多有5-6个变体。在我的示例中,前4个dict连续返回,但所有4个dict都有单独的API调用。@gagrot,在示例中,
    data
    是所有行的列表。我的代码依赖于“行”,将相同的['N.,'Batch','Sem','Sub']组合在一起,
    数据可以是从API生成行的生成器。你没有提供任何关于API的信息,所以我只是使用了一个列表。我想你搞错了,兄弟。不存在初始数据列表。所有API都在运行中被调用,单个dict也在运行中被填充。所以我使用了所有1个API,它返回1个dict,然后我们使用代码将其附加到最终列表中。然后第二个API,第二个Dict,使用代码,再次追加。抱歉说得不清楚
    
    import itertools as it
    
    data = [
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAD', 'Files': 21, 'Type': 'dwg', 'Size(MB)': 98, 'uid': 732854},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAD', 'Files': 8, 'Type': 'pdf', 'Size(MB)': 42, 'uid': 735554},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAD', 'Files': 16, 'Type': 'docx', 'Size(MB)': 104, 'uid': 746748},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAD', 'Files': 8, 'Type': 'pptx', 'Size(MB)': 57, 'uid': 731024},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAM', 'Files': 8, 'Type': 'dwg', 'Size(MB)': 71, 'uid': 737328},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'CAM', 'Files': 8, 'Type': 'docx', 'Size(MB)': 22, 'uid': 376494},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'MIM', 'Files': 8, 'Type': 'pptx', 'Size(MB)': 28, 'uid': 687281},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'MIM', 'Files': 8, 'Type': 'docx', 'Size(MB)': 20, 'uid': 687231},
        {'N.': 'Sam', 'Batch': 2019, 'Sem': 'I', 'Sub': 'MET', 'Files': 20, 'Type': 'pptx', 'Size(MB)': 204, 'uid': 457281},
    ]
    
    preferred_types = ('dwg', 'pdf', 'bmp')
    
    result = []
    
    key = lambda v:(v['N.'], v['Batch'], v['Sem'], v['Sub'])
    
    for _, values in it.groupby(data, key=key):
        values = sorted(values, key=lambda v:v['Type'] not in preferred_types)
        
        result.append(values[0])
        
        result.extend(value for value in values[1:] if value['Type'] in preferred_types)
                
    for row in result:
        print(row)