`for`循环使用生成器,如果用尽则返回不同的值

Ber*_*rdL 2 python for-loop generator python-3.x

我循环遍历一个itertools.permutation对象,为了提高效率,一旦找到该项,循环就会中断.我明白,因为我使用了for循环,StopIteration当生成器耗尽且找不到项目时,我无法捕获错误.

到目前为止,我已经实施了found一面旗帜,但它看起来有点像黑客.

from itertools import permutations

def verify_string(name, compare):
    name = name.lower().split()
    compare = compare.lower().split()
    p = permutations(compare, len(compare))
    found = 0

    for i in p:
        if list(i) == name:
            print(f'Found: {compare} in {name}')
            found = 1
            break

    if not found:
        print('Not Found')

name = 'guido van rossum'
compare = 'van guido rossum'

verify_string(name, compare)
>>Found: ['van', 'guido', 'rossum'] in ['guido', 'van', 'rossum']
Run Code Online (Sandbox Code Playgroud)

我也想过检查if not next(p, ''),看它是否已耗尽,但该项目可能会在生成的最后一个项目找到,将返回True反正.

从Pythonic视图中,是否有一种方法可以管理生成器上的循环,该生成器在找到项目时停止并返回,并且仅在生成器耗尽时返回不同的值.

lig*_*ist 5

Pythonic的方法是使用for-else循环.

from itertools import permutations

def verify_string(name, compare):
    name = name.lower().split()
    compare = compare.lower().split()    
    for i in permutations(compare, len(compare)):
        if list(i) == name:
            print(f'Found: {compare} in {name}')
            break
    else:  # Raymond Hettinger calls this "if no break" condition
        # If we did not break out of the "for loop", execute this.
        print('Not Found')

name = 'guido van rossum'
compare = 'van guido rossum'

verify_string(name, compare)
>>> Found: ['van', 'guido', 'rossum'] in ['guido', 'van', 'rossum']
Run Code Online (Sandbox Code Playgroud)

编辑

我最初的回答是如何避免使用found旗帜,我没有注意你实际上想要做什么.该for-else构造也是一个非常有用且经常被忽略的语言构造,我想强调一下.

但是,如果您只想检查字符串集是否是另一个字符串的排列,那么为什么不呢

match = sorted(name.lower().split()) == sorted(compare.lower().split())
Run Code Online (Sandbox Code Playgroud)

这避免了需要对字符串中的单词进行所有可能的排列.