首页 > 解决方案 > 使用 python3 时出现 Lambda 函数错误

问题描述

我有一段代码适用于 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

我在这里做错了什么?

标签: pythonpython-3.x

解决方案


答案很简单:这是因为它的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,因为如果不尝试获取下一个元素,就无法判断迭代器是否已用尽,并且迭代器没有长度。有关更多信息,请参阅

因此,存在将空​​迭代器传递给 的情况sorted,从而产生另一个空迭代器list。您无法访问位于0空位置的元素list,因此您会得到一个IndexError.

为了解决这个问题,我建议严格评估条件。你可以做这样的事情,用 替换sortedmin因为我们只需要一个值:

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

推荐阅读