【问题标题】:Find minimum non zero value in dictionary (Python)在字典中查找最小非零值(Python)
【发布时间】:2019-02-09 08:38:27
【问题描述】:

我有一本字典,我想获取值为最小非零值的键。

例如给定输入:

{1:0, 2:1, 3:2}

它会返回 2。

【问题讨论】:

  • 你已经尝试过什么?您应该发布您尝试过的内容。
  • 我试图通过以下方式获取密钥:min(diction.items(), key = lambda x:x[1] if x>0) 但我收到错误:SyntaxError: invalid syntax

标签: python python-3.x dictionary min


【解决方案1】:

您可以在 一次 迭代中完成。

d = {1:0, 2:1, 3:2}

# Save the minimum value and the key that belongs to it as we go
min_val = None
result = None
for k, v in d.items():
    if v and (min_val is None or v < min_val):
        min_val = v
        result = k

print(result)

一些假设:

  • 将考虑负值
  • 它将返回找到的第一个键
  • 如果有帮助,min_val 将保持最小值

【讨论】:

    【解决方案2】:

    您可以使用 0 被视为 False 的事实来过滤掉 0 值。然后将next 与生成器表达式一起使用:

    d = {1:0, 2:1, 3:2}
    
    val = min(filter(None, d.values()))
    res = next(k for k, v in d.items() if v == val)  # 2
    

    这只会在具有 1 作为值的重复键的情况下返回 一个 键。对于多个匹配项,您可以使用列表推导:

    res = [k for k, v in d.items() if v == val]
    

    请注意您的文字要求“最小非零”将包含负值。

    性能说明

    上述解决方案是 2-pass,但时间复杂度为 O(n),不可能有比这更低 的复杂度。如@Maor 所示,1-pass O(n) 解决方案是可能的,但这不一定更有效:

    # Python 3.6.0
    
    %timeit jpp(d)  # 43.9 ms per loop
    %timeit mao(d)  # 98.8 ms per loop
    %timeit jon(d)  # 183 ms per loop
    %timeit reu(d)  # 303 ms per loop
    

    用于基准测试的代码:

    from random import randint
    
    n = 10**6
    d = {i: randint(0, 9) for i in range(n)}
    
    def jpp(d):
        val = min(filter(None, d.values()))
        return next(k for k, v in d.items() if v == val)
    
    def mao(d):
        min_val = None
        result = None
        for k, v in d.items():
            if v and (min_val is None or v < min_val):
                min_val = v
                result = k
        return result
    
    def jon(d):
        return min({i for i in d if d[i] != 0})
    
    def reu(d):
        no_zeros = {k: v for k, v in d.items() if v != 0}
        key, val = min(no_zeros.items(), key=itemgetter(1))
        return key
    

    【讨论】:

      【解决方案3】:

      假设dict 被命名为a

      from operator import itemgetter
      
      a = {1:0, 2:1, 3:2}
      # remove zeros
      no_zeros = {k: v for k, v in a.items() if v != 0} # can use `if v`
      # find minimal key and value (by value)
      key, val = min(no_zeros.items(), key=itemgetter(1))
      # key = 2, val = 1
      

      【讨论】:

        【解决方案4】:
        print(min(i for i in dictionary if  dictionary[i] != 0))
        

        这会创建一个没有零的集合并返回该集合中的最小值。虽然值得指出的是,这进行了 2 次迭代,因此比 Maor Refaeli 的解决方案要慢。

        【讨论】:

          【解决方案5】:

          解决方案

          some_dict = {1:0, 2:1, 3:2}
          compare = []
          
          for k, v in some_dict.items():
              if k != 0:
                  compare.append(k)
          
          x = min(compare)
          
          print(x)
          

          我只是将appended 的所有非零keys 转换为list (compare) 然后应用min(compare)

          我们可以重新插入x,并检查它是否指向键1,这是最小的非零key,返回它是value,即0

          >>> print(some_dict[x]) 
          >>> 0
          

          【讨论】:

            猜你喜欢
            • 2020-07-26
            • 2014-10-26
            • 1970-01-01
            • 2015-07-18
            • 2022-06-16
            • 2021-04-04
            • 2013-11-06
            • 2015-01-16
            • 1970-01-01
            相关资源
            最近更新 更多