【问题标题】:Slicing a list of dictionaries and removing one key切片字典列表并删除一个键
【发布时间】:2016-12-24 14:52:17
【问题描述】:

我有一个字典列表,如下所示:

l = [ { "a": 10, "b": 4, "c": 6 },
      { "a": 10, "b": 6, "c": 8 },
      { "a": 13, "b": 3, "c": 9 },
      { "a": 12, "b": 5, "c": 3 },
      { "a": 11, "b": 7, "c": 1 } ]

现在,我想对它进行切片并仅列出一个字典,其中键 a 具有值 10,但从字典中删除键 a。喜欢下面的列表:

nl = [ { "b": 4, "c": 6 },
       { "b": 6, "c": 8 } ]

我可以通过处理l 两次来做到这一点:

l[:] = [d for d in l if d.get("a") == 10]
nl = []
for c in l:
    del c["a"]
    nl.append(c)

有没有更直接的方法可以做到这一点?

【问题讨论】:

  • 您能否澄清一下您是想修改l 还是仅仅能够获得包含更改的新字典?
  • @Karin,我想获得一份新名单并确保 l 安全
  • 听起来不错:) 只是想指出您发布的实现并没有这样做 - 它也会从 l 的内部字典中删除 a
  • @Karin 是的,我的错。应该是nl[:] = ....

标签: python list dictionary slice


【解决方案1】:

可能有更好的方法,但你可以做一个嵌套的字典理解:

[{k:d[k] for k in d if k!="a"} for d in l if d.get("a") == 10]

【讨论】:

    【解决方案2】:

    也许您可以使用 filter 和 map 函数来提高可读性和不变性。

    示例(我没有测试过):

    l = [ { "a": 10, "b": 4, "c": 6 },
      { "a": 10, "b": 6, "c": 8 },
      { "a": 13, "b": 3, "c": 9 },
      { "a": 12, "b": 5, "c": 3 },
      { "a": 11, "b": 7, "c": 1 } ]
    
    l_filtered = filter(lambda x: x.get('a') == 10, l)
    l_filtered_without_a = map(lambda x: {'b': x.get('b'), 'c': x.get('c')}, l_filtered)
    

    【讨论】:

      【解决方案3】:

      类似于 SO 上的This question,用于从字典中删除元素。其余的很简单。

      [ {i:elem[i] for i in elem if i!="a"} for elem in l if elem["a"] == 10]
      

      返回

      [{'b': 4, 'c': 6}, {'b': 6, 'c': 8}]

      【讨论】:

        【解决方案4】:

        在我看来,您工作太努力了,无法使它成为单线。创建两个空列表,并根据a 键的值将每个字典附加到一个或另一个。

        >>> l = [ { "a": 10, "b": 4, "c": 6 },
        ...       { "a": 10, "b": 6, "c": 8 },
        ...       { "a": 13, "b": 3, "c": 9 },
        ...       { "a": 12, "b": 5, "c": 3 },
        ...       { "a": 11, "b": 7, "c": 1 } ]
        >>> l1 = []
        >>> nl = []
        >>> for d in l:
        ...    targetList = l1 if d.get('a') == 10 else nl
        ...    targetList.append(d)
        >>> l1
        [{'a': 10, 'c': 6, 'b': 4}, {'a': 10, 'c': 8, 'b': 6}]
        >>> nl
        [{'a': 13, 'c': 9, 'b': 3}, {'a': 12, 'c': 3, 'b': 5}, {'a': 11, 'c': 1, 'b': 7}]
        >>>
        

        【讨论】:

          【解决方案5】:

          我认为我有一个非常酷的单行代码,它应该非常快并且无论a 是否在字典中都可以工作。它依赖于从字典中弹出返回键的值(如果键不存在,则返回无)以及删除条目的事实。请注意,它确实会改变 l

          l = [ { "a": 10, "b": 4, "c": 6 },
                { "a": 10, "b": 6, "c": 8 },
                { "a": 13, "b": 3, "c": 9 },
                { "a": 12, "b": 5, "c": 3 },
                { "q": 12, "b": 5, "c": 3 },
                { "a": 11, "b": 7, "c": 1 } ]
          
          ret = [d for d in l if "a" in d.keys() and d.pop("a") == 10]
          print ret
          
          >>[{'c': 6, 'b': 4}, {'c': 8, 'b': 6}]
          

          【讨论】:

            【解决方案6】:

            它可以用地图/过滤器在单行中完成

            res = [elem for elem in map(lambda x:{k:v for k,v in x.items() if k != 'a'}, [e for e in filter(lambda y:y.get('a') != 10,a)])]
            

            【讨论】:

              猜你喜欢
              • 2017-11-06
              • 2019-04-30
              • 2021-03-14
              • 2019-09-04
              • 1970-01-01
              • 1970-01-01
              • 2021-05-09
              • 1970-01-01
              • 2021-09-14
              相关资源
              最近更新 更多