【问题标题】:Delete dict elements by index list按索引列表删除dict元素
【发布时间】:2020-01-02 20:30:41
【问题描述】:

我有一个具有相同长度的不同键的字典:

list_in_dict = list(range(0, 10))
test_dict = {"A" : list_in_dict , "B": list_in_dict , "C": list_in_dict}

然后我有一个这样的索引列表:

delete_index_list = [1,5,7]

我想删除键中的所有元素,其中位置对应索引。

我试过了(但完全失败了):

for i in range(len(delete_index_list)):
    del(test_dict["A"][delete_index_list[i]])
    del(test_dict["B"][delete_index_list[i]])
    del(test_dict["C"][delete_index_list[i]])

可能我必须在这里使用列表理解?实现此结果的最紧凑方法是什么:

test_dict 
Out: 
{'A': [0, 2, 3, 4, 6, 8, 9],
 'B': [0, 2, 3, 4, 6, 8, 9],
 'C': [0, 2, 3, 4, 6, 8, 9]}

【问题讨论】:

  • dict 不保证键的顺序。如果您有严格的关系 - 手动删除或使用键和索引之间的映射
  • 按照您构建test_dict 的方式,您只需从键A 中删除项目,因为其他值是对相同list_in_dict 的引用

标签: python list dictionary indexing list-comprehension


【解决方案1】:

你可以试试dictlist comprehension

{k:[elt for ind, elt in enumerate(v) if ind not in delete_index_list] for k,v in test_dict.items() }

完整代码:

# Build data
list_in_dict = list(range(0, 10))
test_dict = {"A" : list_in_dict , "B": list_in_dict , "C": list_in_dict}

# Index to remve
delete_index_list = [1,5,7]

out = {k:[elt for ind, elt in enumerate(v) if ind not in delete_index_list] for k,v in test_dict.items() }
print(out)
# {'A': [0, 2, 3, 4, 6, 8, 9],
#  'B': [0, 2, 3, 4, 6, 8, 9],
#  'C': [0, 2, 3, 4, 6, 8, 9]}

【讨论】:

  • 如果将列表更改为range(1, 10),请检查结果。您要删除 1、5 和 7,而不是 索引。它被您的测试列表中的值和索引相同的事实所掩盖。
  • 你比我快,我也是这样解决的。为你+1,我删除了我的答案:)
  • @glibdud 好点。这是通过enumeration 修复的。谢谢:-)
【解决方案2】:

您的方法的主要问题是,一旦您删除索引1,之前索引5 的内容现在实际上是4。如果delete_items_list 中的项目已排序,您可以通过从列表末尾开始并返回到开头来解决此问题。 (也没有必要弄乱delete_items_list...的索引...这不会造成问题,但我已在此处修复它以帮助提高代码的可读性。)

for i in reversed(delete_index_list):
    del(test_dict["A"][i])
    del(test_dict["B"][i])
    del(test_dict["C"][i])

您可以通过添加另一个 for 循环来减少重复:

for k in test_dict:
    for i in reversed(delete_index_list):
        del(test_dict[k][i])

正如另一个答案中所建议的,如果可以重建 test_dict 中的列表,则可以通过理解来完成。为了正确删除索引而不是值,您需要使用enumerate()

test_dict = {k : [val for i, val in enumerate(v) if i not in delete_index_list] for (k, v) in test_dict.items()}

【讨论】: