我有一段代码可以在python 2.7中工作,但不能在python3.7中工作。在这里,我试图按lambda函数的值进行排序。
def get_nearest_available_slot(self):
"""Method to find nearest availability slot in parking
"""
available_slots = filter(lambda x: x.availability, self.slots.values())
if not available_slots:
return None
return sorted(available_slots, key=lambda x: x.slotNum)[0]
我得到的错误是:
File "/home/xyz/Desktop/parking-lot/parking-lot-1.4.2/parking_lot/bin/source/parking.py", line 45, in get_nearest_available_slot
return sorted(available_slots, key=lambda x: x.slotNum)[0]
IndexError: list index out of range
我在这里做什么错了?
答案 0 :(得分:8)
答案很简单:这是因为filter
的工作原理。
在Python 2中,filter
被热切评估,这意味着一旦调用它,它就会返回一个list
:
filter(lambda x: x % 2 == 0, [1, 2, 3])
输出:
[2]
相反,在Python 3中,filter
被惰性评估;它会产生一个您可以迭代一次的对象,或者一个迭代器:
<filter at 0x110848f98>
在Python 2中,如果if not available_slots
的结果为空,则行filter
停止执行,因为空的list
的值为False
。
但是,在Python 3中,filter
返回一个迭代器,该迭代器的总结果为True
,因为如果不尝试获取迭代器就无法确定迭代器是否已耗尽next元素,并且迭代器没有长度。有关更多信息,请参见this。
因此,存在将空迭代器传递给sorted
并产生另一个空list
的情况。您无法访问空白0
的位置list
上的元素,因此会得到一个IndexError
。
要解决此问题,我建议严格评估条件。您可以执行以下操作,将sorted
替换为min
,因为我们只需要一个值:
def get_nearest_available_slot(self):
"""Method to find nearest availability slot in parking
"""
available_slots = [slot for slot in self.slots.values() if slot.availability]
if available_slots:
return min(available_slots, key=lambda x: x.slotNum)
else:
return None