【问题标题】:searching for element in a dictionary key在字典键中搜索元素
【发布时间】:2014-08-01 19:38:21
【问题描述】:

我有字典

{('22', '83', '75', '5', '8', '7', '9', '12', '16', '17', '22', '23', '24', '18', '14'): 1, 
 ('1', '2', '83', '5', '8', '75', '9', '12', '16', '17', '18', '14'): 1, 
 ('11', '2', '7', '5', '8', '7', '9', '12', '16', '17', '18', '14'): 1}

它的键是元组。

现在我需要搜索其任何键中是否存在一对元素,例如(83,75),并且 我还需要确保8375 按该顺序出现在给定的键中。 因此,对于示例字典中的第一个键,这是正确的,但对于第二个键则不是。

我知道我可以找到带有 8375 的密钥,但我无法验证它们的顺序。

【问题讨论】:

  • 不仅顺序很重要,值也需要彼此相邻。您的第二个键有'83',后跟'75'。您是否也需要搜索更长的键?

标签: python dictionary


【解决方案1】:

请使用元组的索引方式

例如对于第一个键元组 {('22', '83', '75', '5', '8', '7', '9', '12', '16', ' 17'、'22'、'23'、'24'、'18'、'14')

>>> a = ('22', '83', '75', '5', '8', '7', '9', '12', '16', '17', '22', '23', '24', '18', '14')
>>> a.index("83")
1
>>> a.index("75")
2

条件表达式将是:

>>> "83" in a and "75" in a and a.index("83") == a.index("75") - 1
True

【讨论】:

  • @MartijnPieters 请教我为什么它在这里没有用?发帖人问“我无法验证他们的订单”。 index 方法在这里效果很好。
  • @Sheng 你只是太快地抛出你的初始答案,因为 Martijn 的评论肯定适用。现在看起来好多了。
  • @JanVlcinsky 我知道最初的答案很简短。但它显示了解决方案的关键。如果short是错误的,论坛应该在发帖前进行更严格的字数检查。反正我会注意不要发短的。
  • @Sheng:您的 FGITW 答案未完成。只有您最近的编辑才能使其成为实际答案。
  • @MartijnPieters 感谢您的提醒。我会遵循风格。
【解决方案2】:

如果你能发现 83 存在,而 75 不存在,那么它显然不是成对存在的。如果两者都存在,那么您可以测试一下 83 和 75 的索引是否相差等于 1。

【讨论】:

    【解决方案3】:

    一个简单的 for 循环就足够了。如果未找到 '83''75'index 函数将抛出 ValueError。执行此操作的 Pythonic 方法是 try-except 块。:

    my_dict = {('22', '83', '75', '5', '8', '7', '9', '12', '16', '17', '22', '23', '24', '18', '14'): 1, 
               ('1', '2', '83', '5', '8', '75', '9', '12', '16', '17', '18', '14'): 1, 
               ('11', '2', '7', '5', '8', '7', '9', '12', '16', '17', '18', '14'): 1}
    keys = []
    for key in my_dict:
        try:
            if key.index('75') - key.index('83') == 1:
                keys.append(key)
        except ValueError:
            pass
    

    如果您想找到在83 之后包含75 的键,无论它是否接近,您都可以使用此版本:

    my_dict = {('22', '83', '75', '5', '8', '7', '9', '12', '16', '17', '22', '23', '24', '18', '14'): 1, 
               ('1', '2', '83', '5', '8', '75', '9', '12', '16', '17', '18', '14'): 1, 
               ('11', '2', '7', '5', '8', '7', '9', '12', '16', '17', '18', '14'): 1}
    keys = []
    for key in my_dict:
        try:
            if '75' in key[key.index('83'):]:
                keys.append(key)
        except ValueError:
            pass
    

    【讨论】:

    • OP 连续要求他们,这将在83 之后添加他们有75 的任何内容
    • @cmd 很好。谢谢!
    • 如果密钥较长怎么办?
    • @MartijnPieters 你能解释一下'如果密钥更长'是什么意思吗?
    • 如果 OP 想要找到 (83, 75, 5)(83, 75, 5, 8) 怎么办?
    【解决方案4】:

    也许您可以检查元组中的第一项是否在任何键中,一旦找到,使用元组切片和len(query) 检索下一个索引并检查它们的相等性。试试这个,虽然我没有测试过。

    query = ('83', '75')
    mydict = {('22', '83', '75', '5', '8', '7', '9', '12', '16', '17', '22', '23', '24', '18', '14'): 1, 
     ('1', '2', '83', '5', '8', '75', '9', '12', '16', '17', '18', '14'): 1, 
     ('11', '2', '7', '5', '8', '7', '9', '12', '16', '17', '18', '14'): 1}
    
    for k in mydict:
        try:
            i = k.index(query[0])
        except ValueError:
            pass
        else:
            if k[i:i+len(query)] == query:
                return k, '->', mydict[k]
    

    【讨论】:

    • 这至少支持搜索更长的元组。 注意:OP 输入查询包含整数,键是 strings 的元组,因此您的代码不会匹配任何内容。然而,这种方法是合理的。
    • 糟糕,对。我修复了查询。我猜 OP 也错过了这一点,但如果没有,mapstr 可能会派上用场!
    【解决方案5】:

    基于迭代器的解决方案可能在这里很方便

    sentinel = object()
    for k in d:
        i = iter(k)
        if '83' in i and next(i, sentinel) == '75':
            print k
    
    ('22', '83', '75', '5', '8', '7', '9', '12', '16', '17', '22', '23', '24', '18', '14')
    

    【讨论】:

      猜你喜欢
      • 2021-09-03
      • 2017-09-15
      • 1970-01-01
      • 1970-01-01
      • 2019-08-20
      • 2020-04-30
      • 2011-07-07
      • 2011-12-02
      • 1970-01-01
      相关资源
      最近更新 更多