You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

python-constraint循环添加约束返回空结果的问题排查

问题原因与解决方案

核心问题:Lambda闭包的延迟绑定

你代码里的问题出在循环中定义lambda约束时的闭包延迟绑定。Python的lambda表达式在定义时不会立即捕获person变量的值,而是在实际执行时才去查找person的当前值。当循环结束后,所有添加的lambda约束都会引用循环最后一次迭代的person对象,也就是["tom", "3:00"]。

所以当你调用my_function([["bob", "2:00"], ["tom", "3:00"]])时,实际添加的两个约束是:

  • 对t_bob:检查x == "3:00"
  • 对t_tom:检查x == "3:00"

再加上AllDifferentConstraint要求两个时间必须不同,这就导致没有符合条件的解,返回空列表。而当只传一个元素时,循环只执行一次,lambda能正确捕获到对应的值,所以结果正常。

修复方案

解决这个问题的关键是让lambda在定义时就捕获当前迭代的person值,有两种常用方法:

方法1:使用默认参数绑定当前值

修改循环内的lambda定义,通过默认参数把当前person[1]的值绑定进去:

for person in List:
    problem.addConstraint(
        (lambda x, target=person[1]: x == target),
        ["t_" + person[0]]
    )

默认参数会在lambda定义时就计算并保存当前person[1]的值,避免后续循环修改带来的影响。

方法2:使用工厂函数生成lambda

如果觉得默认参数不够直观,可以写一个小的工厂函数来生成约束函数:

def create_constraint(target_time):
    return lambda x: x == target_time

for person in List:
    problem.addConstraint(
        create_constraint(person[1]),
        ["t_" + person[0]]
    )

每次循环调用create_constraint时,都会把当前的person[1]作为参数传入,生成一个绑定了该值的lambda函数。

修复后的完整代码

def my_function(List):
    from constraint import Problem, AllDifferentConstraint
    problem = Problem()
    people = ["bob", "tom"]
    times = ["2:00", "3:00"]

    t_vars = list(map(lambda x: "t_" + x, people))
    problem.addVariables(t_vars, times)

    problem.addConstraint(AllDifferentConstraint(), t_vars)

    # 使用默认参数修复闭包问题
    for person in List:
        problem.addConstraint(
            (lambda x, target=person[1]: x == target),
            ["t_" + person[0]]
        )

    return problem.getSolutions()

现在调用my_function([["bob", "2:00"], ["tom", "3:00"]])就能得到预期结果[{'t_bob': '2:00', 't_tom': '3:00'}]了。

内容的提问来源于stack exchange,提问作者MrWhiteee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 02:50:39