[英]Find minimum non zero value in dictionary (Python)
I have a dictionary and I would like to get the key whose value is the minimum nonzero. 我有一本字典,我想获得其值为最小非零值的密钥。
Eg given the input: 例如给出输入:
{1:0, 2:1, 3:2}
It would return 2. 它将返回2。
You can do it on one iteration. 你可以在一次迭代中完成。
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)
Some assumptions: 一些假设:
min_val
will hold the minimum value min_val
将保持最小值 You can use the fact 0
is considered False
to filter out 0
values. 您可以使用事实
0
被视为False
来过滤掉0
值。 Then use next
with a generator expression: 然后使用
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
This will only return one key in the case of duplicate keys with 1
as value. 这只会在重复键的情况下返回一个键,值为
1
。 For multiple matches, you can use a list comprehension: 对于多个匹配,您可以使用列表推导:
res = [k for k, v in d.items() if v == val]
Note your literal ask for "minimum non-zero" will include negative values. 请注意,您的文字要求“最小非零”将包含负值。
Performance note 表现说明
The above solution is 2-pass but has time complexity O( n ), it's not possible to have lower complexity than this. 上述解决方案是2遍,但具有时间复杂度O( n ),不可能具有比这更低的复杂度。 A 1-pass O( n ) solution is possible as shown by @Maor, but this isn't necessarily more efficient:
如@Maor所示,可以使用1遍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
Code used for benchmarking: 用于基准测试的代码:
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
Assuming the dict
is named a
: 假设
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
print(min(i for i in dictionary if dictionary[i] != 0))
this makes a set with no zeros and return the minimum value in that set. 这使得一个没有零的集合并返回该集合中的最小值。 Though it is worth pointing out this makes 2 iterations and is thus slower than Maor Refaeli's solution.
虽然值得指出这会导致2次迭代,因此比Maor Refaeli的解决方案慢。
Solution 解
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)
I just appended
all the non-zero keys
to a list
( compare
) and then applied min(compare)
我只是
appended
所有非零keys
appended
到list
( compare
)然后应用min(compare)
We can plug x
back in and check that it is pointing to the key 1
which is the smallest non-zero key
and that returns it's value
which is 0
我们可以重新插入
x
并检查它是否指向键1
,它是最小的非零key
并返回它的value
0
>>> print(some_dict[x])
>>> 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.