如何使用python的yield语句

2024-10-02 22:37:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个项目的列表,希望生成所有可能的子集。因此,我使用一个递归函数,其中包含项目编号和所有选定项目的列表作为参数。函数以0作为第一个参数调用,并执行以下操作:

  • 它查看由index参数描述的项
  • 它选择它
  • 它用递增的索引参数调用自己
  • 它取消选择项目
  • 它用递增的索引参数调用自己

我需要可能的子集来优化一些东西,但是由于列表会变得很长,所以我不能全部查看。一开始我试图用蛮力来考虑所有的子集,但这是一个天真的想法。现在,新的计划是创建一个贪婪的算法,它接受第一个“有用”的选择:我想查看所有的子集,直到找到一个适合我需要的子集,并认为python的yield语句是正确的选择。下面是一些代码:

def bruteForceLeft(selected,index):
    #left is the list of which i need subsets
    #its a gobal variable. to test the code, just make sure that you have a 
    #list called left in scope
    if index==len(left):
        #print(selected)
        yield selected
    else:
        #the algorithm stores the selection in a tuple of two lists
        #that's necessary since there's a second list called right as well
        #I think you can just ignore this. Think of selected as a list that
        #contains the current selection, not a tuple that contains the current
        #selection on the right as well as the left side.
        selected[0].append(left[index])
        bruteForceLeft(selected,index+1)
        selected[0].pop()
        bruteForceLeft(selected,index+1)

#as you can see I pass a tuple of two empty lists to the function.
#only the first one is used in this piece of code
for option in bruteForceLeft( ([],[]) ,0):
    print(option)
    #check if the option is "good"
    #break

结果是:什么都没有

一开始我以为我在生成子集时出错了,但是在if条件下,您可以看到我有一个带注释的print语句。如果我取消了这个print语句的注释,而是注释掉了yield语句,那么所有可能的选择都会被打印出来,for循环也会中断

使用yield语句,代码运行时不会出错,但也不会执行任何操作。在


Tags: ofthein参数indexthatas语句
1条回答
网友
1楼 · 发布于 2024-10-02 22:37:05

问题是,当递归调用bruteForceLeft时,生成的值不会神奇地从封闭函数中获得。所以,你需要让自己:

def bruteForceLeft(selected,index):
    #left is the list of which i need subsets
    if index==len(left):
        #print(selected)
        yield selected
    else:
        #the algorithm stores the selection in a tuple of two lists
        #that's necessary since there's a second list called right as well
        #I think you can just ignore this. Think of selected as a list that
        #contains the current selection, not a tuple that contains the current
        #selection on the right as well as the left side.
        selected[0].append(left[index])
        for s in bruteForceLeft(selected,index+1):
            yield s
        selected[0].pop()
        for s in bruteForceLeft(selected,index+1):
            yield s

(编辑:实际上我刚测试过这个,你的代码有错误,但我很确定问题是不能再让步)

相关问题 更多 >