I am evaluating successive terms of the look and say sequence (more about it here: https://en.wikipedia.org/wiki/Look-and-say_sequence).
I used two approaches and timed them both. In the first approach, I just iterated over each term to construct the next one. In the second, I used itertools.groupby()
to do the same. The time difference is pretty dramatic, so I made a figure for fun:
What makes itertools.groupby()
so efficient? The code for the two approaches is below:
1st approach:
def find_block(seq):
block = [seq[0]]
seq.pop(0)
while seq and seq[0] == block[0]:
block.append(seq[0])
seq.pop(0)
return block
old = list('1113222113')
new = []
version1_time = []
for i in range(40):
start = time.time()
while old:
block = find_block(old)
new.append(str(len(block)))
new.append(block[0])
old, new = new, []
end = time.time()
version1_time.append(end-start)
2nd approach:
seq = '1113222113'
version2_time = []
def lookandread(seq):
new = ''
for value, group in itertools.groupby(seq):
new += '{}{}'.format(len(list(group)), value)
return new
for i in range(40):
start = time.time()
seq = lookandread(seq)
end = time.time()
version2_time.append(end-start)