Or with next()
:
l = ['Some long text', 'often begins', ' with ', 'impenetrable fog ',
'which ends', ' somewhere further']
startIndex = next((u for u, v in enumerate(l) if 'begins' in v), 0)
finalIndex = next((u for u, v in enumerate(l) if 'ends' in v), 0)
if (startIndex and finalIndex) and (finalIndex > startIndex):
sentence = ' '.join(l[startIndex:finalIndex])
else:
sentence = None
print(sentence)
Similar as list comprehension, execpt it doesn't return a list but the first element it found. if it doesn't found anything, it return an optional element (here '0'
)
This way, if there is no 'begins'
or no 'ends'
in your list, you don't have to print anything. Therefore, this allows you to check either if the 'ends'
comes before the 'begins'
.
I also love list comprehension but sometimes what you need isn't a list.
SOLUTION FOR ADVANCE USER:
The problem with the use of two comprehension list, is that you check twice your list from start and it will fail when ends
comes before start:
l = ['Some long text ends here', 'often begins', ' with ', 'which ends']
^^^
To avoid this, you might use a generator with send()
to only iterate once on your list.
def get_index(trigger_word):
for u, v in enumerate(l):
if trigger_word in v:
trigger_word = yield u
gen = get_index('begins')
startIndex = gen.send(None)
finalIndex = gen.send('ends')
Here, the yield
allows you to get the index without exiting the function.
This is better, but if there is no begins
or ends
in the list, there will be a StopIteration exception. To avoid this, you can just do a infinite loop on yield
0 instead. Now the complete solution will be:
def get_index(l, trigger_word):
for u, v in enumerate(l):
if trigger_word in v:
trigger_word = yield u
while True:
yield 0
def concat_with_trigger_words(l):
gen = get_index(l, 'begins')
startIndex = gen.send(None)
finalIndex = gen.send('ends')
return ' '.join(l[startIndex:finalIndex]) if (startIndex and finalIndex) else None
# Here some list for free lists for your future unitary tests ;)
l_orignal = ['Some long text here', 'often begins', ' with ',
'impenetrable fog ', 'which ends', ' somewhere further']
l_start_with_ends = ['ends', 'often begins', ' with ',
'impenetrable fog ', 'which ends', 'begins']
l_none = ['random', 'word']
l_without_begin = ['fog', 'ends here']
l_without_end = ['begins', 'but never' '...']
print(concat_with_trigger_words(l_orignal)) # often begins with impenetrable fog
print(concat_with_trigger_words(l_start_with_ends)) # often begins with impenetrable fog
print(concat_with_trigger_words(l_none)) # None
print(concat_with_trigger_words(l_without_end)) # None
print(concat_with_trigger_words(l_without_begin)) # None