使用python3时Lambda函数错误

时间:2019-06-10 07:57:20

标签: python python-3.x

我有一段代码可以在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

我在这里做什么错了?

1 个答案:

答案 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