在包含“无”/“假”值的字典上获取具有最小值的键

Posted

技术标签:

【中文标题】在包含“无”/“假”值的字典上获取具有最小值的键【英文标题】:Get key with minimum value on a dictionary that contains 'None' / 'False' values 【发布时间】:2020-03-28 14:08:41 【问题描述】:

我的项目是一个初级的漫游 AI。当它的意识范围内有食物时,它会朝它走去。如果它有不止一种食物,它应该选择最近的。

我将食物作为键存储在字典中,分配给键的值是到所述食物的最后已知距离。 然后我检查字典中距离最短的食物,以便朝它前进。

问题是超出范围的食物被赋值为 None(也尝试过 False),并且在使用时

min(self.vision, key=self.vision.get)

它返回它找到的第一个具有 None/False 值的键。通过在在线编译器上进行测试,我发现在较旧的 python 版本上存在这个错误:

TypeError:不可排序的类型:NoneType()

我猜现在认为 None 类型总是小于数字(也用整数测试)。

我正在尝试结合 lambdas、过滤器、列表、分钟、地图和其他功能,但我想我实际上是愚蠢的。我总是取回值而不是键,或者最终得到一个无济于事的过滤列表。

我也不喜欢创建两个 dicts 的想法,例如“seen”和“unseen” foods,尽管这是一个真正的可能性。

最小的可重现示例: (注释/取消注释底部的第三行以获得错误)

class Test:
    def __init__(self,x,y):
        self.x, self.y = x,y
x = 

for i in range(3):
    for j in range(3):
        x[Test(i,j)] = (i+j)

# x[Test(9,9)] = None
m = min(x, key=x.get)
print(m.x,m.y)

【问题讨论】:

你能提供一个minimal reproducible example 吗?您的字典中似乎有 None 值以及浮点数。您可能需要先过滤掉它们。 如果您要分配值,为什么不使用float('inf') 刚刚添加了一个示例。 float('inf') 听起来正是我想要的! 【参考方案1】:

一种简单的方法:创建 (distance, item) 的元组,不包括 None 的元组,并从中取出最小值:

food = 'bread': 3, 'apple':2, 'pancake': None, 'ham':1

reachable = [(distance, item) for item, distance in food.items() if distance is not None]
closest = min(reachable)[1]
print(closest)
# ham

在元组中将距离放在首位允许它们首先按距离排序,而无需指定排序键。

【讨论】:

非常感谢!我想出了一个有点类似的解决方案,但没有创建一个新列表:#LOOK ALL FOODS AND REGISTERS THE DISTANCE OF THOSE WITHIN RANGE for f in foods: if distPerPoints((self.x,self.y),f.pos) < self.awareness: self.vision[f] = distPerPoints((self.x,self.y),f.pos) else: #ignores completely each food out of range if f in self.vision: del self.vision[f]【参考方案2】:

好的,感谢所有cmets,在社交媒体python组上找到了一个简洁的解决方案!

刚刚在 github 上上传了完整的项目!如果有人想弄乱它,这是链接: https://github.com/ParovSt/A-Bullet-Called-Life/blob/master/README.md

这是某个人向我展示的解决方案:

min(x, key = lambda k: x[k] if x[k] != None else float('inf'))

这是我在此解决方案之前遇到的问题:

for f in foods:
    if distPerPoints((self.x,self.y),f.pos) < self.awareness:
        self.vision[f] = distPerPoints((self.x,self.y),f.pos)
    else:
        #ignores completely each food out of range
        if f in self.vision:
            del self.vision[f]
#[...]

    self.target = min(self.vision, key=self.vision.get)

【讨论】:

以上是关于在包含“无”/“假”值的字典上获取具有最小值的键的主要内容,如果未能解决你的问题,请参考以下文章

Python:从字典中获取具有最小值但有多个最小值的键

使用具有多个值的键创建 NSDictionary

python 中关于字典的键

包含具有重复值的字典的字典组数组

比较两个字典(键,值)并返回不具有相同值的键

从 NSDictionary 获取包含 NSNumber 布尔值的键列表,其中值为 @YES