I am looping over an itertools.permutation object and for efficiency, the loop breaks once the item is found. I understand that because I used the for loop I am unable to catch the StopIteration error when the generator is exhausted and the item is not found.
So far I have implemented a found flag, but it seems kinda hacky.
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']
I also thought of checking if not next(p, '') to see if it is exhausted but the item might be found in the generator's last item and will return True anyways.
From a Pythonic view, is there a way to manage looping over a generator that stops and return when an item is found and returns a different value only when the generator is exhausted.
The Pythonic way is to use a for-else loop.
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']
My initial reply was to how to avoid using the found flag and I wasn't paying attention to what you were actually trying to do. The for-else construct is also a very useful and often neglected language construct that I wanted to highlight.
However, if you just want to check if the set of string is a permutation of another, then why not just
match = sorted(name.lower().split()) == sorted(compare.lower().split())
This avoids the need to go through all possible permutation of the words in the string.
From a Pythonic view, is there a way to manage looping over a generator that stops and return when an item is found and returns a different value only when the generator is exhausted.
As you don't actually return anything - if you fix that part of your function, you'll return None if there are no matches:
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')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With