使用正则表达式搜索键的 Python 字典值

Python dictionary search values for keys using regular expression

提问人:Programmer 提问时间:5/29/2012 更新时间:12/29/2021 访问量:108876

问:

我正在尝试实现在 Python 字典中搜索特定键值的值(使用正则表达式作为键)。

例:

我有一个 Python 字典,其值如下:

{'account_0':123445,'seller_account':454545,'seller_account_0':454676, 'seller_account_number':3433343}

我需要搜索键为“seller_account”的值?我写了一个示例程序,但想知道是否可以做得更好。主要原因是我不确定正则表达式并错过了一些东西(例如我如何为以“seller_account”开头的键设置 re):

#!usr/bin/python
import re
my_dict={'account_0':123445,'seller_account':454545,'seller_account_0':454676, 'seller_account_number':3433343}

reObj = re.compile('seller_account')

for key in my_dict.keys():
        if(reObj.match(key)):
                print key, my_dict[key]

~ home> python regular.py

seller_account_number 3433343
seller_account_0 454676
seller_account 454545

评论

0赞 eumiro 5/29/2012
如果您必须经常搜索密钥的这些部分,则您的数据结构可能有问题。
11赞 Mike Williamson 7/14/2020
每当我遇到像 eumiro 这样的评论时,我都会觉得有人想象一个完美的、整体的世界,在这个世界里,OP 可以完全控制她工作的各个方面。你真的认为@Programmer可以控制接收到的数据结构吗?除非是学校项目,否则我非常怀疑。

答:

8赞 cval 5/29/2012 #1
def search(dictionary, substr):
    result = []
    for key in dictionary:
        if substr in key:
            result.append((key, dictionary[key]))   
    return result

>>> my_dict={'account_0':123445,'seller_account':454545,'seller_account_0':454676, 'seller_account_number':3433343}
>>> search(my_dict, 'seller_account')
[('seller_account_number', 3433343), ('seller_account_0', 454676), ('seller_account', 454545)]

评论

1赞 psychemedia 8/14/2014
您可以通过使其不区分大小写来使搜索更通用一些,例如,通过将搜索词和键转换为小写:if substr.lower() in key.lower()
61赞 Cédric Julien 5/29/2012 #2

如果你只需要检查以 开头的键,则不需要正则表达式,只需使用 startswith()"seller_account"

my_dict={'account_0':123445,'seller_account':454545,'seller_account_0':454676, 'seller_account_number':3433343}

for key, value in my_dict.iteritems():   # iter on both keys and values
        if key.startswith('seller_account'):
                print key, value

或以one_liner方式:

result = [(key, value) for key, value in my_dict.iteritems() if key.startswith("seller_account")]

注意:对于python 3.X的使用,请替换为并且不要忘记添加。iteritems()items()()print

评论

3赞 Dr. Jan-Philip Gehrcke 5/29/2012
要再次成为字典,您可以使用 or(在 Python 2.7 中)代替 list comprehension 。resultdict(){...}[...]
7赞 Arash 10/2/2019
只是在 Python3 中,您必须使用 而不是items()iteritems()
1赞 user5054 4/16/2021
但是你正在失去字典的效率,不是吗?Access 不再是 O(1),因为您必须对字典元素进行 for 循环。
1赞 Shayne 4/25/2021
无论如何,您都需要手动搜索每个键,因此效率对我们来说并没有太大作用
11赞 Andrew Kesterson 5/12/2013 #3

你可以用dpath解决这个问题。

http://github.com/akesterson/dpath-python

dpath 允许您在键上使用 glob 语法搜索字典,并筛选值。你想要的是微不足道的:

$ easy_install dpath
>>> dpath.util.search(MY_DICT, 'seller_account*')

...这将返回一个与该球体匹配的所有键的合并大字典。如果您只想要路径和值:

$ easy_install dpath
>>> for (path, value) in dpath.util.search(MY_DICT, 'seller_account*', yielded=True):
>>> ... # do something with the path and value

评论

5赞 Jesse 5/12/2013
安德鲁,我会小心在没有披露的情况下发布。你所有的答案都是关于dpath的。你显然看起来很喜欢(或一部分)dpath;如果你是,我想提醒你,披露你的隶属关系是强制性的。
19赞 dalloliogm 2/25/2015
从github url来看,Andrew似乎是dpath的主要作者。我看不出它有什么问题,因为它是麻省理工学院许可的软件。
7赞 Ehsan Ahmadi 2/5/2021 #4

您可以使用“re”和“filter”的组合。例如,如果要在 OS 模块中搜索哪些方法的方法名称中包含“stat”一词,则可以使用下面的代码。

import re 
import os
r = re.compile(".*stat.*")
list(filter(r.match, os.__dict__.keys()))

结果是:

['stat', 'lstat', 'fstat', 'fstatvfs', 'statvfs', 'stat_result', 'statvfs_result']

我认为原始问题中的性能问题是在使用“re”模块找到键后进行key_value搜索。如果密钥的一部分是可互换的,我们不能使用“startswith”。所以“re”是一个不错的选择。另外,我使用过滤器来获取所有匹配键的列表并列出它们,这样我们就可以用简单的 [DICT[k] for k in LIST 返回所有值。

评论

0赞 Thomas Fritz 3/6/2021
请问您的回答与搜索词典的原始问题有什么关系?
1赞 Ehsan Ahmadi 3/6/2021
我认为原始问题中的性能问题是使用“re”模块建立密钥后key_value搜索,如果密钥的一部分是可互换的,则我们不能使用“startswith”,因此“re”是一个不错的选择。另外,我使用过滤器来获取所有匹配键的列表并列出它们,这样我们就可以用简单的 [DICT[k] for k in LIST 返回所有值。
0赞 Clintm 12/29/2021
@EhsanAhmadi您应该在答案中添加您的评论以使其更准确
0赞 Peter Kahn 4/28/2023
这是一个很好的解决方案。谢谢你。忘记了过滤器
0赞 Clintm 12/29/2021 #5

就像我如何为以“seller_account”开头的键设置 re 一样

reObj = re.compile('seller_account')

应该是:

reObj = re.compile('seller_account.*')