【问题标题】:How do I return the difference between a list of dictionaries and a list of objects based on a specific key:value only如何返回字典列表和基于特定键的对象列表之间的差异:仅值
【发布时间】:2019-12-14 03:14:59
【问题描述】:

我想根据现有条目与用户传递的内容之间的差异来更新表中的条目。

例如:

通过了什么:

users: [
    {"id": 1, "email": "email1@gmail.com"}, 
    {"id": 2, "email": "email2@gmail.com"}
]

以及已经存在的:

user_playground = UserPlaygroundModel.query.filter_by(playground=playground).all()

# This will be a list of UserPlayground objects
user_playground = [
    {id=1, playground=sandbox},
    {id=3, playground=sandbox}
]

所以这意味着 1 留在表中,2 将被添加,3 将被删除。

我想输出传递的内容和已经存在的内容之间的差异,然后根据该差异更改条目。

users_to_add = {id=2, "email": "email2@gmail.com"}

users_to_delete = {id=3}

有更好的方法吗?

【问题讨论】:

  • 这两者的期望输出是什么?添加 2 删除 3 是什么意思
  • 我认为他希望基于用户的ids 和 user_playground 之间的 AND 操作来保留 user_playground 的输出
  • 那么,您有一个由用户传递的列表 (a),还有一个来自数据库 (b) 的列表?
  • set([1,2])-set([1,3]) 给出{2}(添加),set([1,3])-set([1,2]) 给出{3}(删除),set([1,3]) & set([1,2]) 给出{1}(留下)
  • @Artog 是的。我根据与用户具有一对多关系的游乐场名称查询数据库。然后我尝试删除未通过的用户并添加之前不存在的用户。

标签: python python-3.x flask


【解决方案1】:

如果我理解正确,我认为这就是您所需要的:

users = [
    {"id": 1, "email": "email1@gmail.com"},
    {"id": 2, "email": "email2@gmail.com"}
]

user_play =[
    {"id":1, "playground": "sandbox"},
    {"id":3, "playground": "sandbox"}
]


users_to_add = [u for u in users if u.get('id') not in [x.get('id') for x in user_play]]

users_to_delete = [u for u in user_play if u.get('id') not in [x.get('id') for x in users]]

print(users_to_add) # output : [{'id': 2, 'email': 'email2@gmail.com'}]

print(users_to_delete) # output : [{'id': 3, 'playground': 'sandbox'}]

【讨论】:

  • 这正是我想要的!
  • @TeaZulo 很高兴能帮到你
  • 有没有办法只返回特定的键而不是在同一个循环中返回所有键?例如,而不是 print(users_to_delete) # output : [{'id': 3, 'playground': 'sandbox', "capacity": 32}] 只返回 print(users_to_delete) # output : [{'id': 3, "capacity": 32}]
  • @TeaZulo 当然可以,你可以试试这样的: t = [{'id': 3, 'playground': 'sandbox', "capacity": 32}] temp = [{ k,v} for k,v in t[0].items() if k != "playground"] # 注意 t 是一个列表,这就是为什么使用 t[0] 会给你列表中的第一个字典。如果您只有字典,实现会有所不同。希望有帮助
【解决方案2】:

您需要添加的用户是“我从帖子中获得的所有不在数据库中的用户”。同样,您要删除的用户是“我的数据库中没有在我的帖子中获得的所有用户”。

这可以在 python 中使用两行来实现:

# All users supplied from post body (i guess?) that is not in the db
users_to_add = [u for u in users_from_post if u.id not in [x.id for x in user_playground]]

# All users from db that was not supplied by the post (i think?)
users_to_delete = [u for u in user_playground if u.id not in [x.id for x in users_from_post]]

如果你有很多用户,可以做一些事情来优化它,但这个想法是正确的。

【讨论】:

  • 我根据和用户一对多关系的游乐场名称查询数据库。然后我试图删除未通过的用户并添加以前不存在的用户。你是对的,但是主体有 user_playground 没有的键,反之亦然,所以如果我这样做,它只会返回所有内容而不是 ID 的差异。
  • 没错,假设users 列表来自某个帖子或其他内容,那么这应该会为您提供两个您可以用来删除/添加的列表
  • 我将进行编辑以澄清这一点,并且也只是选择直接按 id 进行比较,因为我猜测对象引用不一样
猜你喜欢
  • 1970-01-01
  • 2015-09-03
  • 1970-01-01
  • 1970-01-01
  • 2015-01-16
  • 2013-04-12
  • 1970-01-01
  • 1970-01-01
  • 2018-02-10
相关资源
最近更新 更多