首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >比较两个字典列表中值的Pythonic方法

比较两个字典列表中值的Pythonic方法
EN

Stack Overflow用户
提问于 2015-01-22 02:05:28
回答 6查看 459关注 0票数 3

我刚开始使用Python,在使用Python的时候,我仍然试图远离C++编码技术,所以如果这是一个微不足道的问题,请原谅我。我似乎找不到最毕不过的方法来做这件事。

我有两份名单。两个列表中的单个dicts可能包含嵌套的dicts。(如果你好奇的话,这实际上是Yelp的一些数据。)第一个dicts列表包含如下条目:

代码语言:javascript
复制
{business_id': 'JwUE5GmEO-sH1FuwJgKBlQ',
 'categories': ['Restaurants'],
 'type': 'business'
 ...}

第二个dicts列表包含如下条目:

代码语言:javascript
复制
{'business_id': 'vcNAWiLM4dR7D2nwwJ7nCA',
 'date': '2010-03-22',
 'review_id': 'RF6UnRTtG7tWMcrO2GEoAg',
 'stars': 2,
 'text': "This is a basic review",
 ...}

我想要做的是提取第二个列表中与第一个列表中特定类别匹配的所有条目。例如,如果我对餐馆感兴趣,我只想要第二个列表中的实体,其中business_id与第一个列表中的business_id匹配,而单词Restaurants出现在categories的值列表中。

如果我在SQL中将这两个列表作为表,我将对business_id属性执行一个联接,然后只使用一个简单的筛选器来获取我想要的行( Restaurants in categories,或类似的内容)。

这两个列表非常大,因此我遇到了效率和内存空间问题。在我把所有这些都塞进SQL数据库之前,有人能给我一些提示吗?我和潘达玩过一些,所以我在这方面的经验有限。我在合并过程中遇到了麻烦。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2015-01-22 02:23:06

假设您的列表名为l1l2

来自l1的所有元素

代码语言:javascript
复制
[each for each in l1]

l1中带有Restaurant类别的所有元素:

代码语言:javascript
复制
[each for each in l1
      if 'Restaurants' in each['categories']]

l2中的所有元素将idl1中的元素与Restaurant类别匹配:

代码语言:javascript
复制
[x for each in l1 for x in l2 
   if 'Restaurants' in each['categories']
   and x['business_id'] == each['business_id'] ]
票数 2
EN

Stack Overflow用户

发布于 2015-01-22 02:25:26

让我们定义字典的示例列表:

代码语言:javascript
复制
first = [
        {'business_id':100, 'categories':['Restaurants']},
        {'business_id':101, 'categories':['Printer']},
        {'business_id':102, 'categories':['Restaurants']},
        ]

second = [
        {'business_id':100, 'stars':5},
        {'business_id':101, 'stars':4},
        {'business_id':102, 'stars':3},
        ]

我们可以分两步提取感兴趣的项目。第一步是收集属于餐馆的业务ids列表:

代码语言:javascript
复制
ids = [d['business_id'] for d in first if 'Restaurants' in d['categories']]

第二步是获取对应于这些ids的dicts:

代码语言:javascript
复制
[d for d in second if d['business_id'] in ids]

这导致:

代码语言:javascript
复制
[{'business_id': 100, 'stars': 5}, {'business_id': 102, 'stars': 3}]
票数 2
EN

Stack Overflow用户

发布于 2015-01-22 02:33:09

这很棘手,我玩得很开心。我会这么做的:

代码语言:javascript
复制
def match_fields(business, review):
    return business['business_id'] == review['business_id'] and 'Restaurants' in business['categories']

def search_businesses(review):
    # the lambda binds the given review as an argument to match_fields
    return any(lambda business: match_fields(business, review), business_list)

answer = filter(search_businesses, review_list)

这是我发现的最易读的方法。我不太喜欢超过一行的理解列表,而三行实际上是在推动它。如果您希望这看起来更简洁,只需使用较短的变量名。为了清晰起见,我更喜欢长的。

我定义了一个函数,如果一个条目可以在列表之间匹配,则返回true;还有一个函数,它帮助我搜索检查列表。然后,我可以说:去掉任何在业务列表中没有匹配条目的评审。此模式适用于列表之间的任意检查。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28080188

复制
相关文章

相似问题

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