Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 查找其键与子字符串匹配的字典项_Python_Dictionary_Substring_Key - Fatal编程技术网

Python 查找其键与子字符串匹配的字典项

Python 查找其键与子字符串匹配的字典项,python,dictionary,substring,key,Python,Dictionary,Substring,Key,我有一本这样构造的大词典: programs['New York'] = 'some values...' programs['Port Authority of New York'] = 'some values...' programs['New York City'] = 'some values...' ... 如何返回键提到“new york”(不区分大小写)的程序的所有元素?在上面的示例中,我希望获得所有这三个项目 编辑:字典相当大,预计会随着时间的推移而变大。一个iterit

我有一本这样构造的大词典:

programs['New York'] = 'some values...' 
programs['Port Authority of New York'] = 'some values...' 
programs['New York City'] = 'some values...'
...
如何返回键提到“new york”(不区分大小写)的
程序的所有元素?在上面的示例中,我希望获得所有这三个项目


编辑:字典相当大,预计会随着时间的推移而变大。

一个
iteritems
和一个生成器表达式将执行以下操作:

[value for key, value in programs.items() if 'new york' in key.lower()]
d={'New York':'some values',
    'Port Authority of New York':'some more values',
    'New York City':'lots more values'}

print list(v for k,v in d.iteritems() if 'new york' in k.lower())    
输出:

['lots more values', 'some more values', 'some values']

您可以提前生成所有子字符串,并将它们映射到各自的键

#generates all substrings of s.
def genSubstrings(s):
    #yield all substrings that contain the first character of the string
    for i in range(1, len(s)+1):
        yield s[:i]
    #yield all substrings that don't contain the first character
    if len(s) > 1:
        for j in genSubstrings(s[1:]):
            yield j

keys = ["New York", "Port Authority of New York", "New York City"]
substrings = {}
for key in keys:
    for substring in genSubstrings(key):
        if substring not in substrings:
            substrings[substring] = []
        substrings[substring].append(key)
然后可以查询
子字符串
,以获取包含该子字符串的键:

>>>substrings["New York"]
['New York', 'Port Authority of New York', 'New York City']
>>> substrings["of New York"]
['Port Authority of New York']
优点:

  • 通过子字符串获取密钥的速度与访问字典的速度一样快
缺点:

  • 生成
    子字符串
    会在程序开始时产生一次性成本,所需时间与
    程序
    中的键数成比例
  • 子字符串
    将随着
    程序
    中的键数近似线性增长,从而增加脚本的内存使用量
  • genSubstrings
    与密钥大小相关的性能为O(n^2)。例如,“纽约港务局”生成351个子字符串

您应该使用由提供的蛮力方法,直到证明其速度太慢为止

这里有一些东西可以复制数据,以提供更快的查找。它只适用于搜索整词的情况,也就是说,你永远不需要匹配“纽约最好的百吉饼”,因为“约克”和“约克”是不同的词

words = {}
for key in programs.keys():
    for w in key.split():
        w = w.lower()
        if w not in words:
            words[w] = set()
        words[w].add(key)


def lookup(search_string, words, programs):
    result_keys = None
    for w in search_string.split():
        w = w.lower()
        if w not in words:
            return []
        result_keys = words[w] if result_keys is None else result_keys.intersection(words[w])
    return [programs[k] for k in result_keys]

如果单词必须按顺序排列(即“York New”不应匹配),您可以对
结果键的短列表应用蛮力方法

,这通常称为松弛字典,可以使用后缀树有效地实现

这种方法使用的内存在关键帧上是线性的,这是最优的,搜索时间在正在搜索的子字符串长度上是线性的,这也是最优的

我在python中找到了这个库,它实现了这一点


没错。如果你的字典很大,不要指望它会很快。@markransem我刚想补充说我的字典很大,而且会越来越大。它一直在做
程序。get('new york')
到目前为止速度非常快。如果字典中的所有键对应用程序来说都太慢,则需要针对此类查询构建数据结构。这可能是某种基于单词的倒排索引或后缀树。@mensi。谢谢我现在正在做改变,看看它的表现如何。我还将研究其他数据结构。这个答案也可以用any条件包装,以获得一个布尔值,判断dict中的任何键是否包含提供的子字符串/条件:
any([x代表程序中的x,如果x.lower()中的'new york'))
感谢您的建议。当门西在上面提到一个反向指数时,我就想到了这一点。在项目的这一点上,我必须选择性能而不是内存使用。所以我也会测试一下。上面写着,找不到页面。我想链接页面现在在这里,但是代码没有被维护。有一个指向叉子的链接,但也被放弃了。