我正在遍历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']
我还考虑过检查if not next(p, '')
是否已用尽,但是可能在生成器的最后一个项目中找到了该项目,并且无论如何都会返回True
。
从Python的角度来看,有一种方法可以管理生成器上的循环,该生成器在找到项目时停止并返回,而仅当生成器为精疲力尽。
答案 0 :(得分:5)
Python方式是使用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']
我的最初答复是如何避免使用found
标志,而我并没有注意您实际上试图做什么。 for-else
构造也是我要强调的非常有用且经常被忽略的语言构造。
但是,如果您只是要检查字符串集是否是另一个字符串的排列,那么为什么不
match = sorted(name.lower().split()) == sorted(compare.lower().split())
这避免了对字符串中所有单词进行所有可能排列的需要。
答案 1 :(得分:1)
有两种方法。一种是测试迭代器的成员资格:
from itertools import permutations
from collections import Counter
def verify_string(name, compare):
if tuple(compare.lower().split()) in permutations(name.lower().split()):
print(f"Found: {compare} in {name}")
else:
print("No match found")
我们还可以完全避免使用三元运算符的功能:
val if val in itr else other_val
如果手头的迭代器恰好是permutations
,那么我们可以不用考虑每个排列并计算单词数就可以逃脱。
def verify_string_fast(name, compare):
if not Counter(compare.lower.split()) - Counter(name.lower.split()):
print(f"Found: {compare} in {name}")
else:
print("No match found")
更一般而言,如果我们有除成员资格之外的其他测试条件,则可以执行以下操作:
def verify_general(val, itr):
if any(compare(val, x) for x in itr):
print("Success")
else:
print("Failure")
关于迭代器中成员资格的说明。据官方documentation称,
对于未定义包含()但可以定义的用户定义的类 定义 iter (),如果x == z的某个值z为 在y上迭代时产生。如果在 迭代,就好像引发了该异常。
由于permutations
具有__iter__
方法,因此可以测试成员资格。
例如,
assert (3, 2, 1) in permutations([1, 2, 3])
答案 2 :(得分:1)
从Pythonic的角度来看,有没有一种方法可以管理 生成器,该生成器在找到项目后停止并返回并返回一个 仅当发电机耗尽时,才可以使用不同的值。
由于您实际上没有返回任何内容-如果您修复了函数的该部分,那么如果没有匹配项,您将返回None
:
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:
return True
name = 'guido van rossum'
compare = 'van guido rossum'
if verify_string(name, compare):
print(f'Found: {compare} in {name}')
else:
print('Not found')