在包含“无”/“假”值的字典上获取具有最小值的键
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)
【讨论】:
以上是关于在包含“无”/“假”值的字典上获取具有最小值的键的主要内容,如果未能解决你的问题,请参考以下文章