【问题标题】:Remove dictionary values based on regex?删除基于正则表达式的字典值?
【发布时间】:2017-11-24 17:13:22
【问题描述】:

我在 Python 中有以下字典

dict1 = {"key1": 2345, "key2": 356, "key3": 773, "key44": 88, "key333": 12, "key3X": 13}

我想删除不遵循"xxx#""xxx##" 模式的键。即,三个字符后跟一个一位整数或两位整数。使用上面的例子,这是:

new_dict = {"key1": 2345, "key2": 356, "key3": 773, "key44": 88}

对于一个或两个键,我创建新字典的方式是使用列表理解:

small_dict = {k:v for k,v in your_dic.items() if v not in ["key333", "key3X"]}

但是,我将如何使用正则表达式/其他字符串方法来删除这些字符串?

单独的问题:如果有特殊例外怎么办,例如一个我想要的键叫"helloXX"

【问题讨论】:

  • @KevinMGranger 手动搜索,就像我对 small_dict 所做的那样。
  • 您已经演示了如何根据布尔条件过滤字典,然后您可以轻松修改它以使用正则表达式。
  • @KevinMGranger 例外是我精神上的症结所在。我想过滤正则表达式或"helloXX"指定的模式之外的两个键?我想这样做的方法是new_dict = {k:dict1[k] for k in dict1 for k in [re.match('[^\d\s]+\d{1,2}$', k), "helloXX"}?
  • @ShanZhengYang:这是一个很好的模式,但是你的条件会失败,因为re.match 将返回一个正则表达式对象,而不是str,所以它不会正确过滤。只需使用该模式,而不是包含该模式和异常字符串的列表。
  • @Billy 谢谢你的澄清。这正是我难以理解的。

标签: python regex string dictionary


【解决方案1】:

只是另一种变体:

import re

dict1 = {"key1": 2345, "key2": 356, "key3": 773, "key44": 88, "key333": 12, "key3X": 13}

rx = re.compile(r'^[A-Za-z]{3}\d{1,2}$')

new_dict = {key: dict1[key] for key in dict1 if rx.search(key)}
print(new_dict)
# {'key44': 88, 'key3': 773, 'key1': 2345, 'key2': 356}

【讨论】:

    【解决方案2】:

    这应该匹配您示例中的所有键以及您的异常情况:

    new_dict = {k:dict1[k] for k in dict1 if re.match('[^\d\s]+\d{1,2}$', k)}
    

    使用带有异常的新示例字典:

    >>> dict1 = {"key1": 2345, "key2": 356, "key3": 773, "key44": 88, "key333": 12, "key3X": 13, "hello13": 435, "hello4325": 345, "3hi33":3}
    >>> new_dict = {k:dict1[k] for k in dict1 if re.match('[^\d\s]+\d{1,2}$', k)}
    >>> print(new_dict)
    {'hello13': 435, 'key44': 88, 'key3': 773, 'key2': 356, 'key1': 2345}
    

    【讨论】:

      【解决方案3】:

      您可以使用正则表达式匹配 3 个字母,后跟一位或两位数字,然后直接跟在字符串末尾 ($):

      >>> import re
      >>> small_dict = {k:v for k,v in dict1.items() if re.match('[a-z]{3}\d{1,2}$',k, re.IGNORECASE)}
      >>> small_dict
      {'key44': 88, 'key3': 773, 'key1': 2345, 'key2': 356}
      

      请注意,re.match 在字符串开头搜索正则表达式:例如,"123key123" 将不匹配。

      如果有例外,您可以在过滤键后添加它们。 如果您想一次性完成:

      small_dict = {k:v for k,v in dict1.items() if re.match('[a-z]{3}\d{1,2}$',k, re.IGNORECASE) or k in ["hello12", "hello34"]}
      

      【讨论】:

      • 最后一行是我感到困惑的地方。谢谢你!
      猜你喜欢
      • 2021-07-19
      • 2014-07-26
      • 1970-01-01
      • 2018-02-28
      • 2017-08-30
      • 1970-01-01
      • 2022-01-22
      • 2011-05-14
      • 1970-01-01
      相关资源
      最近更新 更多