我在JS中使用了以下包含重复项的dict/JSON:
{
0:{
"id" : 1,
"name": "test"
},
1:{
"id" : 2,
"name": "other name"
},
2:{
"id" : 1,
"name": "does not have to be the same name"
},{
"id" : 3,
"name": "but they could be the same"
},
3:{
"id" : 2,
"name": "other name"
}
}我想把它简化为:
{
0:{
"id" : 1,
"name": "test"
},
1:{
"id" : 2,
"name": "other name"
},
2:{
"id" : 3,
"name": "but they could be the same"
}
}标准是id必须是唯一的,而不管项的其余部分是否不同。
对于JS,我使用了以下代码:
const data = [ { "id" : 1, "name": "test" }, { "id" : 2, "name": "other name" }, { "id" : 1, "name": "does not have to be the same name" },{ "id" : 3, "name": "but they could be the same" },{ "id" : 2, "name": "other name" }, ],
unique = Object.values(data.reduce((r, o) => {
r[o.id] = r[o.id] || o;
return r;
},{}));
console.log(unique);然而,我似乎不能用python3.9做同样的事情。我找到了functools.reduce()函数,并尝试将其与lambas一起使用,但dics与JSON对象不同。
发布于 2021-03-04 17:58:49
我使用以下代码解决了这个问题:
data = [i for n, i in enumerate(data) if i['id'] not in {d['id'] for j,d in enumerate(data[n+1:])}] 发布于 2021-03-04 19:33:21
提醒一下,您提供的输入是无效的JSON。根据您的JS,结构应该是这样的。
foo = [
{
"id" : 1,
"name": "test"
},
{
"id" : 2,
"name": "other name"
},
{
"id" : 1,
"name": "does not have to be the same name"
},
{
"id" : 3,
"name": "but they could be the same"
},
{
"id" : 2,
"name": "other name"
}
]也就是说,如果你想要一个使用reduce的解决方案,像这样的东西是可行的。
from functools import reduce
foo = [
{
"id" : 1,
"name": "test"
},
{
"id" : 2,
"name": "other name"
},
{
"id" : 1,
"name": "does not have to be the same name"
},
{
"id" : 3,
"name": "but they could be the same"
},
{
"id" : 2,
"name": "other name"
}
]
# in my opinion, the readability suffers here
# sometimes you need to be ok with using more than one line
result = reduce(lambda x, y: x + [y] if not any(i['id'] == y['id'] for i in x) else x, foo, [])
print(result)一个更具可读性的例子是使用一个实际的函数而不是lambda。
from functools import reduce
foo = [
{
"id" : 1,
"name": "test"
},
{
"id" : 2,
"name": "other name"
},
{
"id" : 1,
"name": "does not have to be the same name"
},
{
"id" : 3,
"name": "but they could be the same"
},
{
"id" : 2,
"name": "other name"
}
]
def build_list(result_list, list_element):
if not any(list_element['id'] == i['id'] for i in result_list):
return result_list + [list_element]
return result_list
result = reduce(build_list, foo, [])
print(result)但这仍然不是我写它的风格。就我个人而言,我会使用set跟踪重复的内容,并完全避免使用comprehension / reduce。
foo = [
{
"id" : 1,
"name": "test"
},
{
"id" : 2,
"name": "other name"
},
{
"id" : 1,
"name": "does not have to be the same name"
},
{
"id" : 3,
"name": "but they could be the same"
},
{
"id" : 2,
"name": "other name"
}
]
result = []
ids = set()
for dct in foo:
if not dct['id'] in ids:
ids.add(dct['id'])
result.append(dct)
print(result)https://stackoverflow.com/questions/66472694
复制相似问题