Пишу скрипт на Python 2.7. В определенной папке есть файлы пользователей, в названии файлов находятся трехзначные ID пользователей. Т.е. есть папка, где куча файлов с названиями "001.user", "002.user", "003.user", ..., "243.user".
Мне нужно скриптом создавать новых пользователей в эту папку. Хочу, чтобы ID подбирался автоматически, т.е. чтобы находилось незанятое число от 0 до 999 (желательно не рандомом, а по порядку).
Это через цикл for нужно делать? Можно ли сделать вот так: скрипт пробует создать файл "001", если произошла ошибка (такой файл уже есть), создается файл "002", снова ошибка - пробует "003", и тут ошибки нет - цикл завершается. Можете подсказать, как это сделать, пожалуйста))))
P.s. И да, я забыл сказать, что юзеры могут удаляться. Т.е. может быть пропуск по ID (005, 006, 007, 009, тут свободен id 008). И этот пропуск желательно заполнять.
У вас есть папка. Изначально пустая. Ваш скрипт должен зайти в директорий, посмотреть, пустая она или нет.
Если директория пустая - генерируем файл 001. и заканчиваем работу.
Если директория не пустая начинаем просматривать файлы последовательно - 001,002.... пока не натыкаемся на последний элемент в этой последовательности. Потом генерируем файл с номером на единицу больший, чем последний встретившийся номер файла. Заканчиваем работу.
Если в будущем у вас некоторая произвольная папка будет уничтожена, скрипт сохранит свою работоспособность.
P.S. Дописанный вами фрагмент вопроса с поочередными попытками открытия файлов - самый неэффективный из всех, которые можно придумать.
Теоретически это зависит от файловой системы и могут быть разные варианты. В худшем случае - счтываете имена всех файлов в директории и делаете то-же, что описано выше, но только над списком имен файлов. В лучшем случае - делаете это непосредственно просматривая директорий. Работая с конкретной ОС вы всегда знаете, какой именно у вас вариант есть смысл использовать.
Получение имен всех файлов в директории в виде списка - одна команда.
os.listdir(directory)
Дальше - дело техники.
Валерий Мамонтов, Я знаю как решить эту задачу, я не автор вопроса. Я спросил вопрос про сотировку потому что в ответе предлагался последовательный перебор файлов, где последний элемент был бы искомым. Поэтому и спросил, а точно ли файлы хранятся в отсортированном массиве.
Спасибо за помощь. Но у меня так же возможны пропуски по id (юзеры могут удаляться). Эти пропуски должны заполнятся. Кроме перебора это можно как-то сделать?
timka228, Вы точно прочитали ответ? И точно поняли?
Я написал - "Если в будущем у вас некоторая произвольная папка будет уничтожена, скрипт сохранит свою работоспособность.".
Поясняю, если какой-то из файлов будет уничтожен, при следующем запуск скрипта и просмотре каталога (то-ли непосредственного, то-ли через создания списка имен, как описано в комментариях) окажется, что последовательность имен прерывается. Т.е. выглядеть этот список будет примерно так [000,001,002,004,005,009]. Обнаружив ПЕРВОЕ отсутствующее число (в примере - 003) его и используйте в качестве имени для нового пользователя. Если пробелов нет, т.е. данные типа таких -[000,001,002,003,004,005,006,007,008,009] - то первое отсутствующее число - 010.
Так, надеюсь, понятно?
timka228 , можно попробовать так (чтобы постоянно не перебирать через цикл):
b = ["011", "012", "003", "004", "005", "006", "007", "008", "009", "010"]
c = list(int(x) for x in b)
d = [x for x in range(len(b))]
# [11, 12, 3, 4, 5, 6, 7, 8, 9, 10] - это список "c"
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - это список "d"
# преобразуем оба списка во множества и ищем разницу
# то есть выводим недостающие элементы:
set(c) - set(d)
# {0, 1, 2} - это результат
Валерий Мамонтов, зачем делать так: b_int = list(int(x) for x in b)
Когда можно так: b_int = [int(x) for x in b]
или вообще вот так: b_int = map(int, b)
Да все можно делать, только зачем, если надо найти строго первый отсутствующий элемент. Не думаю, что ухищрения с переводом в set, а потом обратно ( в Python 2.7 setы не отсортированы, если что) и их сортировать - будут быстрее, чем простая сортировка и поиск окончания первой последовательности.
b = ["011", "012", "003", "004", "005", "006", "007", "008", "009", "010"]
c = list(map(int, b))
d = [x for x in range(len(b)) if x not in c]
print(d)
# [0, 1, 2]
Нет, вы можете получить листинг каталога по маске glob.glob('*.user'), потом взять максимальное (в алфавитно-цифровом порядке) имя, отрезать у него расширение, превратить в целое число, увеличить на единицу, отформатировать нулями слева и создать новый файл.
last = max(glob.glob('*.user')+[''])
new = (last and int(last.split('.')[0]) or 0) + 1