У меня есть серия файлов с именем «x.tif», где «x» — целое число. Мне нужно рассортировать эти файлы по папкам для каждого диапазона номеров.
Верхний уровень папок должен исчисляться миллионами, например 0–999999, 1000000–1999999. Следующий уровень папок должен быть в тысячах, например 0-999, 1000-1999.
Меня сбивает с толку не столько Python, сколько реальная математика для расчета диапазонов.
Конечный результат должен выглядеть примерно так
Конечно, я мог бы сделать это с жестко запрограммированными диапазонами, но я бы предпочел не вводить огромный оператор elif для каждой тысячи в каждом миллионе.
Я пытался использовать divmod(), который работает, как и ожидалось, для чисел ниже одной тысячи, но я не могу понять, что мне нужно сделать, чтобы сделать это динамичным, чтобы он мог предположительно определять диапазоны для любого числа, введенного в него. .
def get_number_range(file_to_move):
file_number = file_to_move
try:
mod_calc_thou = divmod(int(file_number), 1000)
except ValueError:
self.mission_failed(file_to_move, reason = "Not a number")
return False, False
try:
mod_calc_mil = divmod(int(file_number), 1000000)
except ValueError:
return False, False
thousands_range = mod_calc_thou[0] + 999
millions_range = mod_calc_mil[0] + 9999999
thousands_range_folder = f"{str(mod_calc_thou[0])}-{thousands_range}"
millionsths_range_folder = f"{str(mod_calc_mil[0])}-{millions_range}"
print(thousands_range_folder)
print(millionsths_range_folder)
print("First")
get_number_range("530")
#Should output 0-999 and 0-999999
print("Second")
get_number_range("1842888")
#Should output, 1842000-1842999, 1000000-1999999
print("Third")
get_number_range("19874")
#Should output 19000-19999, 0-999999
Вы можете использовать операцию по модулю%
, чтобы вычислить напоминание о номере вашего файла, и вычесть это напоминание, чтобы получить базовый номер fi
диапазонов. Тогда верхнее число диапазонов будет fi
+ Li
- 1.
n = 19874
L1 = 1000000 # Top-level
L2 = 1000 # Next-level
# Compute the base of the ranges
f1 = n - (n % L1)
f2 = n - (n % L2)
# Compute the whole range
r1 = f1, f1 + L1 - 1
r2 = f2, f2 + L2 - 1
print(r2, r1)
Это можно легко адаптировать к более чем двум уровням.
n = 1842888
# The levels in increasing order
levels = [1000, 1000000]
# Compute the base of the ranges
f = [n - (n % l) for l in levels]
# Compute the whole range
r = [(f, f + l - 1) for (f, l) in zip(f, levels)]
print(r)
Вы можете превратить это в обобщенную рекурсивную функцию, которая будет поддерживать любое количество уровней и размер фрагментов. Начните с полного диапазона, который вы разбиваете на фрагменты, а затем рекурсивно переходите к уменьшенному диапазону, соответствующему фрагменту, содержащему номер файла:
def getFolders(FN,spread=1000,levels=2,base=0, maxN=0):
maxN = maxN or spread**(levels+1)
chunk = (maxN-base) // spread
if chunk < spread: return []
base += (FN-base) // chunk * chunk
return getFolders(FN,spread,levels,base,base+chunk) + [f"{base}-{base+chunk-1}"]
выход:
print(getFolders(530)) # ['0-999', '0-999999']
print(getFolders(184288)) # ['184000-184999', '0-999999']
print(getFolders(19874)) # ['19000-19999', '0-999999']
print(getFolders(530,spread=100,levels=3))
# ['500-599', '0-9999', '0-999999']
print(getFolders(184288,spread=100,levels=3))
# ['184200-184299', '180000-189999', '0-999999']
print(getFolders(19874,spread=100,levels=3))
# ['19800-19899', '10000-19999', '0-999999']