关于python:切片字典列表并删除一个键

Slicing a list of dictionaries and removing one key

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

1
2
3
4
5
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的字典列出一个列表。如下所示:

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

我可以通过处理l两次来完成:

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

有没有更直接的方法来实现这一点?


也许有更好的方法,但是你可以做一个嵌套的听写理解:

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

我想我有一个相当酷的一行程序,不管字典里有没有a,它都应该非常快,并且可以工作。它依赖于从字典中弹出返回键的值(如果键不存在,则返回无值)以及删除条目这一事实。但要注意,它确实变异了l

1
2
3
4
5
6
7
8
9
10
11
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}]


类似于这个问题,所以要从字典中删除元素。其余的都很简单。

1
[ {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}]


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

示例(我没有测试它):

1
2
3
4
5
6
7
8
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)

它可以在一个带有map/filter的一行程序中完成

1
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)])]

在我看来,你工作太努力了,不可能把它变成一条直线。创建两个空列表,并根据a键的值将每个dict附加到一个或另一个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> 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}]
>>>