我的问题有点类似于这个问题:https://codereview.stackexchange.com/questions/175079/removing-key-value-pairs-in-list-of-dicts。本质上,我有一个字典列表,我想根据每个字典中两个(或多个)键的唯一组合从列表中删除重复项。
假设我有以下词典列表:
some_list_of_dicts = [
{'a': 1, 'b': 1, 'c': 1, 'd': 2, 'e': 4},
{'a': 1, 'b': 1, 'c': 1, 'd': 5, 'e': 1},
{'a': 1, 'b': 1, 'c': 1, 'd': 7, 'e': 8},
{'a': 1, 'b': 1, 'c': 1, 'd': 9, 'e': 6},
{'a': 1, 'b': 1, 'c': 2, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 3, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 4, 'd': 2, 'e': 3}
]
让我们假设a
,b
和c
的组合必须是唯一的;任何其他值都可以是它们想要的值,但是这三个值的组合对于此列表必须是唯一的。我想采用a
,b
和c
中唯一的组合,保留该组合,并丢弃组合相同的其他所有内容。
通过一些remove_duplicates
函数运行新列表后,它看起来像这样:
new_list = [
{'a': 1, 'b': 1, 'c': 1, 'd': 2, 'e': 4},
{'a': 1, 'b': 1, 'c': 2, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 3, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 4, 'd': 2, 'e': 3}
]
我只能设法解决这个问题:
def remove_duplicates(old_list):
uniqueness_check_list = []
new_list = []
for item in old_list:
# The unique combination is 'a', 'b', and 'c'
uniqueness_check = "{}{}{}".format(
item["a"], item["b"], item["c"]
)
if uniqueness_check not in uniqueness_check_list:
new_list.append(item)
uniqueness_check_list.append(uniqueness_check)
return new_list
但是,这感觉不太像Python。还有一个问题,就是我已经在函数中硬编码了哪些键必须是唯一的。如果我可以将其指定为函数本身的参数会更好,但同样,不确定执行此操作的最佳方式是什么。
答案 0 :(得分:3)
您可以使用dict理解以相反的顺序从字典列表中构建一个dict,以便任何唯一组合中的第一个组合的值都优先。使用operator.itemgetter
获取唯一键作为元组。最后按原始顺序再次颠倒:
from operator import itemgetter
list({itemgetter('a', 'b', 'c')(d): d for d in reversed(some_list_of_dicts)}.values())[::-1]
这将返回:
[{'a': 1, 'b': 1, 'c': 1, 'd': 2, 'e': 4},
{'a': 1, 'b': 1, 'c': 2, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 3, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 4, 'd': 2, 'e': 3}]
答案 1 :(得分:1)
借助跟踪重复项的功能,您可以使用一些列表理解:
Rectangle[] zombies = new Rectangle[60];
Timer timer = new Timer();
int spawnedZombies = 0;
public Zombie(float x, float y, ID id, SpriteSheet ss) {
super(x, y, id, ss);
Delay();
}
public void Delay(){
timer.schedule(task, 0, 1000);
}
TimerTask task = new TimerTask()
{
public void run()
{
Random rand = new Random();
int result = rand.nextInt(6);
if(result == 0){
x = 1000;
y = 200;
}
if(result == 1){
x = 100;
y = 200;
}
if(result == 2){
x = 100;
y = 600;
}
if(result == 3){
x = 1000;
y = 600;
}
if(result == 4){
x = 100;
y = 900;
}
if(result == 5){
x = 1000;
y = 900;
}
spawnedZombies++;
zombies[spawnedZombies - 1] = new Rectangle((int)x, (int)y, 32, 48);
if(spawnedZombies == zombies.length){
task.cancel();
}
}
};
要使用:
def remove_duplicates(old_list, cols=('a', 'b', 'c')):
duplicates = set()
def is_duplicate(item):
duplicate = item in duplicates
duplicates.add(item)
return duplicate
return [x for x in old_list if not is_duplicate(tuple([x[col] for col in cols]))]
您还可以提供不同的列来输入:
>>> remove_duplicates(some_list_of_dicts)
[
{'a': 1, 'c': 1, 'b': 1, 'e': 4, 'd': 2},
{'a': 1, 'c': 2, 'b': 1, 'e': 3, 'd': 2},
{'a': 1, 'c': 3, 'b': 1, 'e': 3, 'd': 2},
{'a': 1, 'c': 4, 'b': 1, 'e': 3, 'd': 2}
]