【问题标题】:Python - "search" dictionary for values contained in multiple keys, regex?Python - “搜索”字典中包含多个键的值,正则表达式?
【发布时间】:2020-11-17 01:17:21
【问题描述】:

以这本矿物质词典为例,以及包含这些矿物质的食物作为矿物质:食物键:值对 (D)-

D = {'copper': {'Tomatoes', 'Onions', 'Eggplant', 'Grapes', 'Bell Peppers'}, 'manganese': {'Tomatoes', 'Onions', 'Eggplant', 'Grapes', 'Garlic', 'Celery', 'Bell Peppers'}, 'magnesium': {'Onions'}, 'phosphorus': {'Onions'}, 'potassium': {'Celery', 'Tomatoes', 'Grapes'}, 'sodium': {'Celery', 'Butter'}, 'salt': {'Celery', 'Butter'}}

我正在尝试编写一个函数(我现在假设是一个正则表达式),它接受 3 种矿物质的字符串,并返回包含这些矿物质的食物的 set。

例如,对于输入:'copper & manganese & phosphorus'

我需要输出为:{Onions} 因为洋葱是唯一含有所有 3 种矿物质的食物。 (使用 AND(不是 OR)逻辑)。

所以我只需要检查字典中包含所有 3 个值的键。

现在我能够想出以下内容,它只使用“OR”逻辑即可满足我的要求。如,它返回包含任何这些值的所有键。

D = {'copper': {'Tomatoes', 'Onions', 'Bell Peppers', 'Eggplant', 'Grapes'}, 'manganese': {'Tomatoes', 'Onions', 'Bell Peppers', 'Celery', 'Eggplant', 'Garlic', 'Grapes'}, 'magnesium': {'Onions'}, 'phosphorus': {'Onions'}, 'potassium': {'Tomatoes', 'Celery', 'Grapes'}, 'sodium': {'Butter', 'Celery'}, 'salt': {'Butter', 'Celery'}}  
mList = ['copper', 'magnesium', 'manganese', 'phosphorus', 'potassium', 'salt', 'sodium']

x = []
y = [D[k] for k in mList if k in D]
for s in y:
   for r in s:
        if r not in x:
            x.append(r)
x = sorted(x)
sx = set(x)
return(sx)

返回:

{'Tomatoes', 'Onions', 'Bell Peppers', 'Celery', 'Eggplant', 'Garlic', 'Grapes'}

【问题讨论】:

    标签: python python-3.x regex


    【解决方案1】:

    所以只是从this answer 扩展一点,您可以简单地使用集合的交集。

    & 运算符将为您提供这些集合的交集,即这些集合共有的任何项目。

    >>> D["copper"] & D["magnesium"]
    {'Onions'}
    

    这实际上只是以下的简写:

    >>> D["copper"].intersection( D["magnesium"] )
    {'Onions'}
    

    更进一步,您可以将其中三个结合起来:

    >>> D["copper"] & D["manganese"] & D["phosphorus"]
    {'Onions'}
    

    应该足够简单,您可以将输入用作查找的字典键!

    【讨论】:

      【解决方案2】:

      正如 Matt 所说,Python 集合允许您基于集合论执行计算:在这种情况下,检查集合之间的交集(或重叠)。

      D = {'copper': {'Tomatoes', 'Onions', 'Bell Peppers', 'Eggplant',
                      'Grapes'}, 
           'manganese': {'Tomatoes', 'Onions', 'Bell Peppers', 'Celery', 
                         'Eggplant', 'Garlic', 'Grapes'}, 
           'magnesium': {'Onions'}, 
           'phosphorus': {'Onions'}, 
           'potassium': {'Tomatoes', 'Celery', 'Grapes'}, 
           'sodium': {'Butter', 'Celery'}, 
           'salt': {'Butter', 'Celery'}}  
      

      基于上面的字典,接受三个参数的函数可以计算并返回字典中存储的三个集合的交集:

      def food_intersection(3_mineral_string, D):
          food1, food2, food3 = 3_mineral_string.split('_')  
                                # i.e. 'copper_magnesium_phosphorus'
                                # The split function creates a list w/ 3 elements
                                # that list can be immediately 'unpacked'
                                # and each element can be associated w/ a 
                                # separate variable (i.e. food1)
                                # Your technique (in the comments) of breaking out the 
                                # list items via index: food1 = myList[0]
                                # also can work.
                      
      
          # food1, food2, food3 = 3_mineral_string.split()    
                                  # we can do this if the food string is
                                  # separated by spaces instead. 
      
          return D[food1] & D[food2] & D[food3]
      

      用你的样品食物来称呼它:

      food_intersection('copper_magnesium_phosphorus', D)
      

      产量:

      {'Onions'}
      

      在上述函数中,& 运算符告诉 Python 调用集合上的 .intersection() 方法。

      由于 D[food*] 为我们输入的每种食物返回一个集合,我们只需使用 & 运算符对所有集合进行 OR 运算,只留下每个集合中存在的值。

      幸运的是,Python 允许我们将所有这些链接在一行中。

      【讨论】:

      • 非常感谢你们的意见。就我而言,该函数将 3 种矿物作为一个字符串。然后将该字符串解析为一个列表。就像这样,function(3_mineral_string, D) 然后被转换为包含矿物质 [“铜”、“镁”、“磷”] 的列表。所以我想我应该首先为每个项目制作 3 个单独的列表,然后使用相交?
      • 也可以做 l1 = myList[0] l2 = myList[1] l3 = myList[2], D[l1] & D[l2] & D[l3]?对吗?
      • 让我知道额外的澄清帮助。如果是,请随时接受答案。
      猜你喜欢
      • 1970-01-01
      • 2023-03-16
      • 2023-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-02
      相关资源
      最近更新 更多