【问题标题】:Filter list of dictionaries by key value - return answers as a list of dictionaries按键值过滤字典列表 - 将答案作为字典列表返回
【发布时间】:2020-02-09 06:25:43
【问题描述】:

我有一个要过滤的字典列表。

[{"Slope": -0.562, "Count": 3},
 {"Slope": -0.362, "Count": 6},
 {"Slope": -0.762, "Count": 8},
 {"Slope": -0.562, "Count": 12},
 {"Slope": 2.5, "Count": 34},
 {"Slope": 1.52, "Count": 2},
 {"Slope": .56, "Count": 6}]

我的目标是获取两个字典的列表。一个具有“最高计数和正斜率”,另一个具有“最高计数和负斜率”。

我的计划是过滤掉所有正面和负面的,然后对每个列表进行排序,然后使用每个列表的第一条记录创建一个新列表。

排序列表对我来说不是问题,我有这个!

lines_lst.sort(key=lambda i: i['lines_count'])

但是当我尝试这个时过滤似乎不起作用,因为它返回一个字典。

positive_lines = next(item for item in lines_lst if item["Slope"] > 0)

有没有人有一个最终得到以下解决方案?

[{"Slope": -0.562, "Count": 12},{"Slope": 2.5, "Count": 34}]

【问题讨论】:

    标签: python list dictionary filter


    【解决方案1】:

    要解决帕特里克回答中的其他信息,您可以这样做以首先对否定/肯定列表进行排序:

    positives = sorted((v for v in data if v['Slope'] >= 0), key=lambda x: x['Count'])
    negatives = sorted((v for v in data if v['Slope'] < 0), key=lambda x: x['Count'])
    
    # positives:
    # [{'Slope': 1.52, 'Count': 2}, {'Slope': 0.56, 'Count': 6}, {'Slope': 2.5, 'Count': 34}]
    
    # negatives:
    # [{'Slope': -0.562, 'Count': 3}, {'Slope': -0.362, 'Count': 6}, {'Slope': -0.762, 'Count': 8}, {'Slope': -0.562, 'Count': 12}]
    

    此时获取最大值很简单。只需检索最后一个元素:

    max_pox = positives[-1]     # {'Slope': 2.5, 'Count': 34}
    max_neg = negatives[-1]     # {'Slope': -0.562, 'Count': 12}
    

    或者,如果您更喜欢列表形式:

    [x[-1] for x in (negatives, positives)]
    
    # [{'Slope': -0.562, 'Count': 12}, {'Slope': 2.5, 'Count': 34}]
    

    【讨论】:

      【解决方案2】:

      您想要 max 和 min .. 使用它们并应用合适的键功能 - 实际上使用元组您只需要 max:

      data = [{"Slope": -0.562, "Count": 3},
              {"Slope": -0.362, "Count": 6},
              {"Slope": -0.762, "Count": 8},
              {"Slope": -0.562, "Count": 12},
              {"Slope": 2.5, "Count": 34},
              {"Slope": 1.52, "Count": 2},
              {"Slope": .56, "Count": 6}]
      
      m1 = max(data, key= lambda x: (x["Slope"]>0, x["Count"]))
      m2 = max(data, key= lambda x: (x["Slope"]<0, x["Count"]))
      
      result = [m1,m2]
      
      print(result)
      

      输出:

      [{'Slope': 2.5, 'Count': 34}, {'Slope': -0.562, 'Count': 12}]
      

      元组按第一个值排序,然后是第二个值 - 您可以构建元组并将它们用作最大键函数。

      【讨论】:

      • @bradSolomon 这将需要更少的计算 - 同意 - 但排序会将那些具有负斜率和最少计数的那些放在后面 - 不是完全需要的?
      • 效果惊人!!但是......事实证明,我可能并不总是有一对积极和消极的观点。你知道我怎样才能将每个正斜率值和负斜率值排列成一个有序列表(按“计数”)吗?然后我可以检查两者的长度并在那之后添加一些额外的条件?
      • @Lew 您可能想使用 BradSolomons 或 Vasilis 方法:列表理解:a,b = sorted( (i for i in data if i["Slope"] &lt; 0), key = lambda x:x["Count"]), sorted( (i for i in data if i["Slope"] &gt;= 0), key = lambda x:x["Count"]) 或使用 filter( ) 函数来做同样的事情。不过,您应该在这两种情况之一中包含 "Slope" == 0,否则您将消除这些值。
      【解决方案3】:

      为负斜率创建一个 Count2 键。然后按 Count2 排序,取第一个和最后一个元素。

      lines_lst = [{"Slope": -0.562, "Count": 3},
       {"Slope": -0.362, "Count": 6},
       {"Slope": -0.762, "Count": 8},
       {"Slope": -0.562, "Count": 12},
       {"Slope": 2.5, "Count": 34},
       {"Slope": 1.52, "Count": 2},
       {"Slope": .56, "Count": 6}]
      
      
      for i in range(len(lines_lst)):
          lines_lst[i]['Count2'] = lines_lst[i]['Count']*lines_list[i]['Slope']/abs(lines_list[i]['Slope'])
      
      lines_lst.sort(key=lambda i: i['Count2'])
      
      [lines_lst[0], lines_lst[-1]]
      
      

      【讨论】:

        【解决方案4】:

        您可以将generator expression 传递给max()

        >>> max((d for d in lines_lst if d["Slope"] > 0), key=lambda d: d["Count"])
        {'Slope': 2.5, 'Count': 34}
        >>> max((d for d in lines_lst if d["Slope"] < 0), key=lambda d: d["Count"])
        {'Slope': -0.562, 'Count': 12}
        

        当然,这个解决方案会迭代lines_lst 两次。如果你有一个非常大的输入,你可以贪婪地遍历它一次,跟踪正在运行的 max/min:

        import sys
        
        max_pos, max_neg = {"Count": -sys.maxsize}, {"Count": -sys.maxsize}
        for d in lines_lst:
            ct = d["Count"]
            if d["Slope"] > 0 and ct > max_pos["Count"]:
                max_pos = d
            elif d["Slope"] < 0 and ct > max_neg["Count"]:
                max_neg = d
        

        但在 Python 领域,这可能仅在您的输入非常庞大且难以处理时才有价值。

        请注意,在这两种情况下,对max_pos/max_neg 的进一步修改构成对lines_lst 成员的修改,因为这些成员是可变字典。

        【讨论】:

          【解决方案5】:

          这行得通吗?

          data = [{"Slope": -0.562, "Count": 3},
          {"Slope": -0.362, "Count": 6},
          {"Slope": -0.762, "Count": 8},
          {"Slope": -0.562, "Count": 12},
          {"Slope": 2.5, "Count": 34},
          {"Slope": 1.52, "Count": 2},
          {"Slope": .56, "Count": 6}]
          positive_lines = []
          negative_lines = []
          for i in range(len(data)):
              if data[i]["Slope"] < 0:
                  negative_lines.append(data[i])
              else:
                  positive_lines.append(data[i])
          max_counts = []
          max_counts.append(max(positive_lines, key=lambda x:x['Count']))
          max_counts.append(max(negative_lines, key=lambda x:x['Count']))
          print(max_counts)
          

          输出:

          [{'Slope': 2.5, 'Count': 34}, {'Slope': -0.562, 'Count': 12}]
          

          【讨论】:

            【解决方案6】:

            你可以这样做:

            inList = [{"Slope": -0.562, "Count": 3},
            {"Slope": -0.362, "Count": 6},
            {"Slope": -0.762, "Count": 8},
            {"Slope": -0.562, "Count": 12},
            {"Slope": 2.5, "Count": 34},
            {"Slope": 1.52, "Count": 2},
            {"Slope": .56, "Count": 6}]
            
            maximum = max(filter(lambda elem: elem['Slope'] > 0, inList), key=lambda e: e['Count'])
            minimum = max(filter(lambda elem: elem['Slope'] < 0, inList), key=lambda e: e['Count'])
            

            这将返回:

            {'Slope': 2.5, 'Count': 34}
            {'Slope': -0.562, 'Count': 12}
            

            【讨论】:

              猜你喜欢
              • 2022-12-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-05-17
              • 2020-02-06
              • 1970-01-01
              相关资源
              最近更新 更多