首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python3 reduce函数

Python3 reduce函数
EN

Stack Overflow用户
提问于 2021-03-04 17:58:49
回答 2查看 32关注 0票数 0

我在JS中使用了以下包含重复项的dict/JSON:

代码语言:javascript
复制
{
  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"
  }
}

我想把它简化为:

代码语言:javascript
复制
{
  0:{
    "id" : 1,
    "name": "test"
  },
  1:{
    "id" : 2,
    "name": "other name"
  },
  2:{
    "id" : 3,
    "name": "but they could be the same"
  }
}

标准是id必须是唯一的,而不管项的其余部分是否不同。

对于JS,我使用了以下代码:

代码语言:javascript
复制
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对象不同。

EN

回答 2

Stack Overflow用户

发布于 2021-03-04 17:58:49

我使用以下代码解决了这个问题:

代码语言:javascript
复制
data = [i for n, i in enumerate(data) if i['id'] not in {d['id'] for j,d in enumerate(data[n+1:])}] 
票数 0
EN

Stack Overflow用户

发布于 2021-03-04 19:33:21

提醒一下,您提供的输入是无效的JSON。根据您的JS,结构应该是这样的。

代码语言:javascript
复制
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的解决方案,像这样的东西是可行的。

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66472694

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档