【问题标题】:How do I filter a dictionary based on the partial string matches?如何根据部分字符串匹配过滤字典?
【发布时间】:2017-08-01 14:47:35
【问题描述】:

我有一个值字典:

dic = {1: "a1+b+c", 2: "a1+c+v", 3: "a1+z+e", 4: "a2+p+a", 5: "a2+z+v", 6: "a3+q+v", ...} 

我在 Flask 中有一个页面,其中包含字典中每个部分字符串值的复选框,例如复选框“a”、“b”、“c”等。在页面上,复选框位于 a1、a2、a3 等组中。

我需要根据选中的复选框的值通过部分值过滤字典,例如,在a1组中选择“c”时,它会返回:

 1: a1+b+c
 2: a1+c+v

从a2组中选择“z”时,会返回:

 5: "a2+z+v"

产生错误的代码是:

sol = [k for k in dic if 'a1' in k]

有人能指出我正确的方向吗?

【问题讨论】:

    标签: python string python-3.x dictionary lookup


    【解决方案1】:

    你可以用一个很短的函数轻松解决这个问题:

    def lookup(dct, *args):
        for needle in args:
            dct = {key: value for key, value in dct.items() if needle in value}
        return dct
    

    例如:

    >>> dic = {1: "a1+b+c", 2: "a1+c+v", 3: "a1+z+e", 4: "a2+p+a", 5: "a2+z+v", 6: "a3+q+v"}
    >>> lookup(dic, "a1", "c")
    {1: 'a1+b+c', 2: 'a1+c+v'}
    

    但是,这总是需要遍历每个“针”的所有键。如果您有一个帮助字典(我将在此处使用 collections.defaultdict)存储与一根针匹配的所有键(假设 + 应该是您字典中的分隔符),您可以做得更好:

    from collections import defaultdict
    
    helperdict = defaultdict(set)
    for key, value in dic.items():
        for needle in value.split('+'):
            helperdict[needle].add(key)
    

    helperdict 现在包含与值的特定部分匹配的所有键:

    >>> print(dict(helperdict))
    {'z': {3, 5}, 'p': {4}, 'a1': {1, 2, 3}, 'a3': {6}, 'v': {2, 5, 6}, 'a2': {4, 5}, 'e': {3}, 'b': {1}, 'a': {4}, 'c': {1, 2}, 'q': {6}}
    

    并且使用set.intersection 可以让您快速获取不同组合的所有匹配项:

    >>> search = ['a2', 'z']
    >>> matches = set.intersection(*[helperdict[needle] for needle in search])
    >>> {match: dic[match] for match in matches}
    {5: 'a2+z+v'}
    

    它肯定比第一种方法更长,并且需要更多的外部内存,但如果您打算执行多个查询,它会快得多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-01
      • 1970-01-01
      • 2023-03-19
      • 2022-01-19
      • 2021-12-18
      • 2017-12-23
      • 1970-01-01
      相关资源
      最近更新 更多