您可以使用 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