【问题标题】:Filter list of dictionaries过滤字典列表
【发布时间】:2015-09-09 07:57:40
【问题描述】:

这是我的例子:

dictlist = [{'first': 'James', 'last': 'Joule'}, 
            {'first': 'James','last': 'Watt'},
            {'first': 'Christian','last': 'Doppler'}]

我正在尝试获取姓氏。如果这是在模型中,代码将是:

getdata = Name.objects.filter(name="Christian")
getLastName = getdata.last

我会得到"Doppler"

【问题讨论】:

标签: python list dictionary


【解决方案1】:

这是一个非常简单的列表理解解决方案:

>>> dictlist = [{'first': 'James', 'last': 'Joule'}, {'first': 'James','last': 'Watt'},{'first': 'Christian','last': 'Doppler'}]
>>> [x['last'] for x in dictlist if x['first'] == 'Christian']
['Doppler']

【讨论】:

  • 这就是我最初的想法,但这会导致一个包含单个字符串的列表,我认为这不是最佳的。
  • 是的,我想这是真的,+1
【解决方案2】:
dictlist = [{'first': 'James', 'last': 'Joule'}, {'first': 'James','last': 'Watt'},{'first': 'Christian','last': 'Doppler'}]
the_jameses = [d for d in dictlist if d['first'] == 'James']

生成的 list 仅包含:

[{'first': 'James', 'last': 'Joule'}, {'first': 'James', 'last': 'Watt'}]

【讨论】:

    【解决方案3】:

    首先,我们可以有一个简单的脚本,它只使用内置的python filter method,这可能已经足够了:

    fl = list(filter(lambda x: x['first'] == 'Christian', dictlist))
    
    # you can't use `.property` because this is a dictionary, not a object
    fl[0]['last']
    # returns Doppler
    

    我知道你的例子是一个 Django 代码,所以如果你想让它更加动态,以便你能够通过字典中的任何键进行过滤:

    def dict_filter(dictlist: list, key: str, value: str) -> list:
        return list(filter(lambda x: x.get(key) == value, dictlist))
    
    dict_filter(dictlist, 'first', 'Christian')
    # similar to django's filter method returns a queryset, this returns a list:
    # [{'first': 'Christian', 'last': 'Doppler'}]
    
    dict_filter(dictlist, 'last', 'Doppler')
    # returns [{'first': 'Christian', 'last': 'Doppler'}]
    
    dict_filter(dictlist, 'last', 'notfound')
    # returns []
    

    以及使用python filter method 来创建与Django 的QuerySet.get 方法类似的函数的示例:

    def dict_get(dictlist: list, key: str, value: str) -> list:
        ret = list(filter(lambda x: x.get(key) == value, dictlist))
        if len(ret) == 0:
            raise Exception('Not Found')
        if len(ret) > 1:
            raise Exception(f'Found more than 1 object with {key}={value}')
        return ret[0]
    
    dict_get(dictlist, 'first', 'Christian')
    # returns {'first': 'Christian', 'last': 'Doppler'}
        
    dict_get(dictlist, 'first', 'Christians')
    # raises Exception: Not Found
    
    dict_get(dictlist, 'first', 'James')
    # raises Exception: Found more than 1 object with first=James
    

    希望对你有帮助!

    【讨论】:

      【解决方案4】:

      这样的东西应该可以工作

      last_name = ''
      
      for d in dictList:
        if d['first'] == 'Christian':
          last_name = d['last']
          break
      

      【讨论】:

        【解决方案5】:

        我有时喜欢用next:

        next((d['last'] for d in dictlist if d['first'] == 'Christian'), None)
        # 'Doppler'
        

        第一个参数是一个迭代器,第二个(可选)参数是没有找到匹配条目时返回的默认值。

        注意:这只会返回第一个匹配结果。因此,如果您希望有多条记录与您的“查询”匹配,那就不好了。

        【讨论】:

          【解决方案6】:
          for comp in dictlist:
              if comp["first"] == 'Christian':
                  return comp["last"]
          

          【讨论】:

          • dictlistlist,而不是 dict
          猜你喜欢
          • 1970-01-01
          • 2016-03-25
          • 1970-01-01
          • 2023-03-23
          • 1970-01-01
          • 2015-12-22
          • 1970-01-01
          • 2020-04-08
          • 1970-01-01
          相关资源
          最近更新 更多