Detecting consecutive integers in a list
From the docs:
>>> from itertools import groupby
>>> from operator import itemgetter
>>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
>>> for k, g in groupby(enumerate(data), lambda (i, x): i-x):
... print map(itemgetter(1), g)
...
[1]
[4, 5, 6]
[10]
[15, 16, 17, 18]
[22]
[25, 26, 27, 28]
You can adapt this fairly easily to get a printed set of ranges.
Find consecutive integers in a list
This is because you only check the next number. When you want the second number (like 9 or 3), you have to include a check for the previous number too. This will make the if
a bit longer, but it'll work.
num=[8,9,4,1,2,3]
for i in range(len(num)):
if (
( # check for the next number
i + 1 != len (num) and # don't check the end of the list
num[i]+1==num[i+1]
) or ( # check for the previous number
i != 0 and # don't check before the list
num [i-1] == num [i] - 1
)
): print('Con',num[i])
Also, I had to remove the -1
in your range, because I already do a manual check, and as pointed out, this prvented 3 from being shown.
Finding sequence of consecutive numbers on lists
You can greatly simplify your code by repeatedly looking for the next number in
the next list.
def find( list_of_lists ):
for element in list_of_lists[0]:
start = element
next = element
for list in list_of_lists[1:]:
next+=1
print( "looking for {} in {}".format(next, list))
if not next in list:
return 'fail'
return [x for x in range(start,next+1)]
a = [[143], [144, 210, 270], [145]]
find(a)
looking for 144 in [144, 210, 270]
looking for 145 in [145]
[143, 144, 145]
Edit: a corrected version
def find( list_of_lists ):
num = len(list_of_lists)
for start in list_of_lists[0]:
try:
print( "starting with", start )
next = start
last = start + num - 1
for list in list_of_lists[1:]:
next+=1
print( "looking for {} in {}".format(next, list))
if not next in list:
raise KeyError()
elif next == last:
return [x for x in range(start,next+1)]
except KeyError:
pass
return 'fail'
find(a)
starting with 1
looking for 2 in [3, 2, 6]
looking for 3 in [5, 7, 4]
starting with 3
looking for 4 in [3, 2, 6]
starting with 5
looking for 6 in [3, 2, 6]
looking for 7 in [5, 7, 4]
[5, 6, 7]
Counting consecutive numbers in a list
You could take an approach like this:
def countlist(random_list):
retlist = []
# Avoid IndexError for random_list[i+1]
for i in range(len(random_list) - 1):
# Check if the next number is consecutive
if random_list[i] + 1 == random_list[i+1]:
count += 1
else:
# If it is not append the count and restart counting
retlist.append(count)
count = 1
# Since we stopped the loop one early append the last count
retlist.append(count)
return retlist
Identify groups of continuous numbers in a list
more_itertools.consecutive_groups
was added in version 4.0.
Demo
import more_itertools as mit
iterable = [2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 20]
[list(group) for group in mit.consecutive_groups(iterable)]
# [[2, 3, 4, 5], [12, 13, 14, 15, 16, 17], [20]]
Code
Applying this tool, we make a generator function that finds ranges of consecutive numbers.
def find_ranges(iterable):
"""Yield range of consecutive numbers."""
for group in mit.consecutive_groups(iterable):
group = list(group)
if len(group) == 1:
yield group[0]
else:
yield group[0], group[-1]
iterable = [2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 20]
list(find_ranges(iterable))
# [(2, 5), (12, 17), 20]
The source implementation emulates a classic recipe (as demonstrated by @Nadia Alramli).
Note: more_itertools
is a third-party package installable via pip install more_itertools
.
Identify groups of continuous numbers in a list
more_itertools.consecutive_groups
was added in version 4.0.
Demo
import more_itertools as mit
iterable = [2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 20]
[list(group) for group in mit.consecutive_groups(iterable)]
# [[2, 3, 4, 5], [12, 13, 14, 15, 16, 17], [20]]
Code
Applying this tool, we make a generator function that finds ranges of consecutive numbers.
def find_ranges(iterable):
"""Yield range of consecutive numbers."""
for group in mit.consecutive_groups(iterable):
group = list(group)
if len(group) == 1:
yield group[0]
else:
yield group[0], group[-1]
iterable = [2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 20]
list(find_ranges(iterable))
# [(2, 5), (12, 17), 20]
The source implementation emulates a classic recipe (as demonstrated by @Nadia Alramli).
Note: more_itertools
is a third-party package installable via pip install more_itertools
.
Related Topics
Turn String into a List and Remove Carriage Returns (Python)
Winerror 10049: the Requested Address Is Not Valid in Its Context
Python 3D Polynomial Surface Fit, Order Dependent
Python | Make the Percentage of a List
Python Not Working in the Command Line of Git Bash
Python Check Multi-Level Dict Key Existence
How to Save Opened Page as Pdf in Selenium (Python)
Number of Common Letters in Two Strings
I Want to Multiply Two Columns in a Pandas Dataframe and Add the Result into a New Column
Check If Key Exists in a Python Dict in Jinja2 Templates
Change Date Formats in CSV With Python 3
What Is the Correct Format to Write Float Value to File in Python
How to Skip Blank Line While Reading CSV File Using Python
How to Test If a Column Exists and Is Not Null in a Dataframe
How to Create an Automatically Updating Gui Using Tkinter
How to Make Print() Accept the User Input in Same Line