<p><code>lambda</code>只是<em>语法</em>,允许您在表达式中创建函数对象(<code>def functionname(..): ...</code>是一个<em>语句</em>,不能在表达式中使用语句)。所以lambda只是创建了一个函数对象,没有什么特别的。你不能在运行时用函数来改变另一个函数的本地命名空间,不行</p>
<p>从评论来看,你似乎在问如何使用回调函数来解决问题,但我认为你还不完全了解问题空间,也不知道<code>list.sort(key=...)</code>是如何工作的。Python的sort实现显式地调用<code>key</code>回调,根据选择,被调用的函数传递信息,sort函数根据返回的内容改变行为;key函数不能选择返回值的结果。在</p>
<p>在我看来,你问错了问题。在</p>
<p>您试图解决的问题是<a href="https://en.wikipedia.org/wiki/Knapsack_problem" rel="nofollow noreferrer"><em>Knapsack Problem</em></a>的子集;您有一个<em>无界的</em>变量,因为<em>我可以根据需要组合列表“input_list”的任意多个元素(允许重复)</em>。在</p>
<p>试图用<code>itertools</code>来解决它是错误的方法;<code>itertools</code>函数将生成许多不正确的组合。实际上,您是在为输出大小1到目标大小生成重复(<em>multisets</em>)的所有组合,因此您可以为每个给定大小生成<a href="https://en.wikipedia.org/wiki/Multiset#Counting_multisets" rel="nofollow noreferrer">calculate the number of such multisets</a>,并将它们相加:</p>
<pre><code>def multiset_size(n, k):
return int(factorial(k + n - 1) / (factorial(k) * factorial(n - 1)))
generated = sum(multiset_size(len(input_list), i + 1) for i in range(target_number_of_packages))
</code></pre>
<p>对于您的玩具示例,有6个输入,目标大小为4,您将生成209个不同的组合,但只有5个可行的组合。这是一个巨大的<em>40.8组合浪费</em>每个可行的输出!随着输入大小的增大,这个比率只会变得(非常)糟糕。在</p>
<p>全背包问题通常用<a href="https://stackoverflow.com/questions/1065433/what-is-dynamic-programming"><em>dynamic programming</em> approach</a>来解决。编程<a href="https://en.wikipedia.org/wiki/Chrestomathy" rel="nofollow noreferrer">chrestomathy</a>网站<em>Rossettacode.org网站</em>有一个<a href="https://rosettacode.org/wiki/Knapsack_problem/Unbounded/Python_dynamic_programming" rel="nofollow noreferrer">great example in Python on how to use DP for an unbounded knapsack solution</a>。基本上,您为每个级别的容量(从零到最大)保留一个“sacks”表,并保持该表的更新,以查看将当前项添加到具有该项空间的sack中是否会产生比该sack的最佳组合更好(更有价值)的sack。在</p>
<p>但当产生所有可能的组合时,最好使用自己的迭代或递归方法。这里没有现成的<code>itertools</code>函数可以使用,使用回调函数也不会使这变得更容易。在</p>
<p>从DP解决方案中抽出一片叶子,迭代解决方案将使用一系列<em>堆</em>的麻袋,并将这些麻袋复制到下一堆,因为您向每个有空间的袋子中添加更多这样的项目:</p>
^{pr2}$
<p>这个解决方案恰好使用<code>itertools.repeat()</code>,但这只是因为它便于从sack中的计数器生成最终输出。在</p>
<p>对于您的玩具示例,使用与背包问题相同的<code>(value, size)</code>格式,将生成:</p>
^{3}$
<p>这只会产生实际可行的组合,而不会产生更多。在</p>
<p>该函数与完整解决方案的不同之处在于,这里保留了所有可能的组合,而不是仅保留组合项的最佳值的一个组合。因为我们生成的是所有的组合,所以不需要像链接DP方法那样按值比率对项目进行排序(排序有助于避免在循环中复制太多不太理想的解决方案)。在</p>
<p>递归版本<a href="https://stackoverflow.com/a/52667107/100297">schwobaseggl produced</a>基本上也是这样做的;为给定的容量创建sack,递归调用为下一个更大的容量添加更多的项。我的方法正好是迭代的,这样就不会遇到Python的递归限制,并且它会在找到结果时生成结果(就像<code>itertools</code>一样)。递归版本还被迫重复连接列表(N==递归深度的O(N^2)操作),因此迭代方法要快得多。在</p>