Skip to content

Instantly share code, notes, and snippets.

@Liametc
Created March 18, 2021 17:35
Show Gist options
  • Save Liametc/e757400b17c5445f77c3ede15dadc92a to your computer and use it in GitHub Desktop.
Save Liametc/e757400b17c5445f77c3ede15dadc92a to your computer and use it in GitHub Desktop.
Group frame numbers by step and display as string
from itertools import chain, groupby
def group_frame_numbers(frame_range, range_char="-", step_char="x", sep=","):
"""
Take a list of frame numbers and group them according to step.
i.e [1, 4, 5, 6, 12, 15, 18, 22, 25, 29, 33] -> 1,4-6,12-18x3,22,25-33x4
:param frame_numbers: A list[int] of frame numbers representing a frame range.
:param range_char: The character to denote a range i.e "1-2". Default is "-".
:param step_char: The character to use to denote a step i.e "x3". Default is "x".
:param sep: The separator character between grouped ranges i.e "1-3,8-9". Default is ",".
:returns: A str representing the frame range.
"""
if not frame_range:
return ""
frame_range.sort()
def get_frame_step(items):
return items[1] - items[0]
frame_range_strs = []
if len(frame_range) == 1:
frame_range_strs = [str(frame_range[0])]
else:
grouped_ranges = []
for step, ranges in groupby(
zip(frame_range[:-1], frame_range[1:]), get_frame_step
):
this_range = set(chain(*ranges))
if len(grouped_ranges):
prev_range = grouped_ranges[-1][1]
if len(prev_range) > 2 or len(prev_range) == len(this_range):
this_range.difference_update(prev_range)
else:
prev_range.difference_update(this_range)
grouped_ranges.append((step, this_range))
frame_range_strs = []
for step, current_range in grouped_ranges:
if not current_range:
continue
start = min(current_range)
end = max(current_range)
if start != end:
frame_range_str = "{}{}{}".format(start, range_char, end)
if abs(step) > 1:
frame_range_str += "{}{}".format(step_char, step)
else:
frame_range_str = str(start)
frame_range_strs.append(frame_range_str)
return sep.join(frame_range_strs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment