Yves Daoust's answer is right, it makes no sense to imitate it. It seems like a trick and that you must understand this and understand the behavior and implement it directly.
Eaves method, but here is the actual implementation of a similar one:
def transform(string): a = string.find('A') + 1 b = string.find('B', 0, a or len(string)) + 1 return 'C' * string.startswith('C') + 'B' * (b>0) + 'A' * (a>0)
I searched for the first βAβ, then searched for βBβ to the left of it (or in the entire line if there was no βAβ). This tells me whether "B" and "A" belong to the exit. For "C", I just need to check the beginning of the line. Although I potentially scan the whole line twice, and not just once, as Yves suggests, using the find function makes it pretty fast, about 100 times faster than just looping through the line βmanuallyβ and just looking for βAβ, (which is only at the end of my test line):
>>> from timeit import timeit >>> s = 'C' * 100000000 + 'BA' >>> timeit(lambda: transform(s), number=1) 0.10583857561359977 >>> timeit(lambda: next(x for x in s if x == 'A'), number=1) 10.957446603791382
You can do this with just one scan, using lstrip('C') to find the first character other than 'C' and faster than doing it manually, but it uses extra memory and is still much slower than find
>>> timeit(lambda: s.lstrip('C'), number=1) 2.411250071361735
Regular expressions may also do this, but even just scanning my test string as soon as finding βAβ takes longer than my entire transform :
>>> timeit(lambda: re.search('A', s), number=1) 0.13403880409939006
Stefan pochmann
source share