在字典中查找最小非零值(Python)

在字典中查找最小非零值(Python),python,python-3.x,dictionary,min,Python,Python 3.x,Dictionary,Min,我有一个字典,我想得到一个值为最小非零的键 例如,给定输入: {1:0, 2:1, 3:2} 它将返回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 = [

我有一个字典,我想得到一个值为最小非零的键

例如,给定输入:

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

它将返回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所示,一次通过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
来自随机导入randint
n=10*6
d={i:randint(0,9)表示范围(n)内的i}
def jpp(d):
val=min(过滤器(无,d.values())
返回next(k表示k,如果v==val,则在d.items()中为v)
主席(d):
最小值=无
结果=无
对于d.项()中的k,v:
如果v和(最小值为无或v
假设
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

你可以在一次迭代中完成

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)
d={1:0,2:1,3:2}
#保存最小值和属于它的密钥
最小值=无
结果=无
对于d.项()中的k,v:
如果v和(最小值为无或v
一些假设:

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

这将生成一个没有零的集合,并返回该集合中的最小值。尽管值得指出的是,这需要2次迭代,因此比Maor Refaeli的解决方案要慢。

解决方案

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)
我只是
所有非零
键添加到
列表
compare
)中,然后应用
min(compare)

我们可以将
x
插回并检查它是否指向
1
键,该键是最小的非零
,并返回
,即
0

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

你已经试过什么了?您应该发布您尝试的内容。我尝试使用:min(diction.items(),key=lambda x:x[1]如果x>0)获取密钥,但得到的错误是:SyntaxError:无效语法
>>> print(some_dict[x]) 
>>> 0