I have a sumranges () function that sums all ranges of consecutive numbers found in a tuple of tuples. To illustrate:
def sumranges(nums): return sum([sum([1 for j in range(len(nums[i])) if nums[i][j] == 0 or nums[i][j - 1] + 1 != nums[i][j]]) for i in range(len(nums))]) >>> nums = ((1, 2, 3, 4), (1, 5, 6), (19, 20, 24, 29, 400)) >>> print sumranges(nums) 7
As you can see, it returns the number of ranges of consecutive digits within the tuple, that is: len ((1, 2, 3, 4), (1), (5, 6), (19, 20), (24), ( 29), (400)) = 7. Tuples are always ordered.
My problem is that my sumranges () are terrible. I hate looking at him. Currently, I just iterate over the tuple and each subhead, assigning 1 if the number is not (1 + the previous number) and sums the total. I feel that I am missing a much simpler way to fulfill my stated goal. Does anyone know a more pythonic way to do this?
Edit: I compared all the answers given so far. Thank you all for your answers.
The benchmarking code is as follows using a sample size of 100K:
from time import time from random import randrange nums = [sorted(list(set(randrange(1, 10) for i in range(10)))) for j in range(100000)] for func in sumranges, alex, matt, redglyph, ephemient, ferdinand: start = time() result = func(nums) end = time() print ', '.join([func.__name__, str(result), str(end - start) + ' s'])
The results are as follows. The actual answer showed that all functions return the correct answer:
sumranges, 250281, 0.54171204567 s alex, 250281, 0.531121015549 s matt, 250281, 0.843333005905 s redglyph, 250281, 0.366822004318 s ephemient, 250281, 0.805964946747 s ferdinand, 250281, 0.405596971512 s
RedGlyph really ends up at speed, but the simplest answer is probably Ferdinand and probably wins for most pythons.