切片字典列表并删除一个键

时间:2016-08-17 19:57:53

标签: python list dictionary slice

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

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)

有没有更简单的方法来实现这一目标?

6 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:2)

我认为我有一个非常酷的单行,应该非常快,并且无论a是否在词典中都有效。它依赖于这样的事实:从字典弹出返回键的值(如果键不存在则返回none)以及删除条目。请注意,它确实会改变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}]

答案 2 :(得分:1)

也许您可以使用函数过滤器和映射来实现可读性和不变性。

示例(我没有测试过):

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 :(得分:1)

类似于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 :(得分:0)

在我看来,你正在努力工作,使其成为一个单行。创建两个空列表,并根据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 :(得分:0)

可以使用map / filter

在单行中完成
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)])]