Created
March 18, 2021 17:35
-
-
Save Liametc/e757400b17c5445f77c3ede15dadc92a to your computer and use it in GitHub Desktop.
Group frame numbers by step and display as string
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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