Python выбор рандомного файла из папки
в Python, что такое хороший или лучший способ генерировать случайный текст для добавления к файлу (имени), который я сохраняю на сервере, просто чтобы убедиться, что он не перезаписывается. Спасибо!
каждый вызов tempfile.NamedTemporaryFile() приводит к другому временному файлу, и его имя можно получить с помощью , например:
как только у вас есть уникальное имя файла, его можно использовать как любой обычный файл. Примечание: по умолчанию файл будет удалены когда это закрытый. Однако, если delete параметр False, файл не автоматически удалять.
полный набор параметров:
также можно указать префикс для временного файла (как один из различных параметров, которые могут быть предоставлены во время создания файла):
дополнительные примеры работы с временными файлами можно найти здесь
можно использовать модуль UUID для генерации случайной строки:
это допустимый выбор, учитывая, что UUID генератор крайне маловероятен для создания дубликата идентификатора (имя файла, в этом случае):
только после генерации 1 миллиарда UUID каждую секунду в течение следующих 100 лет вероятность создания только одного дубликата будет около 50%. Вероятность одного дубликата будет около 50%, если каждый человек на Земле владеет 600 миллионами UUIDs.
общим подходом является добавление метки времени в качестве префикса / суффикса к имени файла, чтобы иметь некоторое временное отношение к файлу. Если вам нужно больше уникальности, вы все равно можете добавить к этому случайную строку.
OP запросил создать random имена не случайный файлы. Времена и UUIDs могут столкнуться. Если вы работаете на одной машине (а не на общей файловой системе), и ваш процесс/поток не будет топтать себя, используйте ОС.getpid (), чтобы получить свой собственный PID и использовать его как элемент уникального имени файла. Другие процессы, очевидно, не получат тот же PID. Если вы многопоточны, получите идентификатор потока. Если у вас есть другие аспекты вашего кода, в котором один поток или процесс может генерировать несколько разных tempfiles, вам может потребоваться использовать другой метод. Скользящий индекс может работать (если вы не держите их так долго или используете так много файлов, вы будете беспокоиться о ролловере). В этом случае достаточно сохранить глобальный хэш/индекс для "активных" файлов.
Извините за длинное объяснение, но оно зависит от вашего точного использования.
Если вы хотите сохранить исходное имя файла как часть нового имени файла, уникальные префиксы длины unifom могут быть созданы:
вызовы àdd_prefix ('style.css') генерирует последовательность типа:
Если вам не нужен путь к файлу, но только случайная строка с предопределенной длиной, вы можете использовать что-то вроде этого.
добавление моих двух центов здесь:
согласно документу python для tempfile.mkstemp, он создает временный файл самым безопасным способом. Обратите внимание, что файл будет существовать после этого вызова:
Я лично предпочитаю, чтобы мой текст был не только случайным/уникальным, но и красивым, поэтому мне нравится lib hashids, который генерирует приятный случайный текст из целых чисел. Можно установить через
pip install hashids
фрагмент:
Краткое Описание:
Hashids-это небольшая библиотека с открытым исходным кодом, которая генерирует короткие, уникальные, не последовательные идентификаторы из чисел.
Каков наилучший способ выбрать случайный файл из каталога в Python?
Изменить. Вот что я делаю:
Это особенно плохо или есть особенно лучший способ?
Что касается вашего отредактированного вопроса: во-первых, я предполагаю, что вы знаете риски использования dircache , а также тот факт, что это устарела с версии 2.6 и удалена с версии 3.0.
Во-вторых, я не вижу, где здесь есть какое-либо состояние гонки. Ваш dircache объект является в основном неизменным (после того, как список каталогов кэширован, он никогда больше не читается), так что нет никакого вреда при одновременном чтении из него.
Кроме этого, я не понимаю, почему вы видите какие-либо проблемы с этим решением. Это хорошо.
Если вы заранее не знаете, какие файлы есть, вам нужно получить список, а затем просто выбрать случайный индекс в списке.
Вот одна попытка:
РЕДАКТИРОВАТЬ . В этом вопросе теперь упоминается страх перед "состоянием гонки", который, как я могу предположить, является типичной проблемой добавления / удаления файлов, когда вы пытаетесь выбрать случайный файл. ,
Я не верю, что есть способ обойти это, кроме как помнить, что любая операция ввода-вывода по своей природе «небезопасна», то есть может привести к сбою. Итак, алгоритм открытия случайно выбранного файла в заданном каталоге должен:
- На самом деле open() файл выбран и обрабатывает ошибку, так как файл больше не может быть там
- Вероятно, ограничьте себя заданным количеством попыток, чтобы он не умер, если каталог пуст или ни один из файлов не читается
Проблема с большинством данных решений заключается в том, что вы загружаете все свои данные в память, что может стать проблемой для больших входов / иерархий. Вот решение, адаптированное из поваренной книги Perl Тома Кристиансена и Ната Торкингтона , Чтобы получить случайный файл в любом месте под каталогом:
Немного обобщая делает удобный скрипт:
Решение, не зависящее от языка:
1) Получить общее количество нет. файлов в указанном каталоге.
2) Выберите случайное число от 0 до [всего нет. файлов - 1].
3) Получить список имен файлов в виде надлежащим образом проиндексированной коллекции или тому подобное.
4) Выберите n-й элемент, где n - случайное число.
Независимо от используемого языка, вы можете прочитать все ссылки на файлы в каталоге в структуру данных, такую как массив (что-то вроде 'listFiles'), получить длину массива. вычислить случайное число в диапазоне от 0 до arrayLength-1 и получить доступ к файлу по определенному индексу. Это должно работать не только в Python.
Если вы хотите, чтобы каталоги были включены, ответ Ювала А. В противном случае:
есть ли встроенный метод для этого? Если нет, как я могу это сделать, не затрачивая слишком много накладных расходов?
не встроенный, но алгоритм R(3.4.2) ("алгоритм резервуара" Уотермана) из "искусства компьютерного программирования" кнута хорош (в очень упрощенной версии):
на num + 2 выдает последовательность 2, 3, 4. The randrange поэтому будет 0 с вероятностью 1.0/(num + 2) -- и это вероятность, с которой мы должны заменить выбранную строку (частный случай размера выборки 1 ссылочного алгоритма - см. книгу кнута для доказательства правильности == и, конечно, мы также в случае небольшого "резервуара", чтобы поместиться в памяти;-). и именно с такой вероятностью мы do так.
для очень длинного файла: ищите случайное место в файле на основе его длины и найдите два символа новой строки после позиции (или новой строки и конца файла). Сделайте снова 100 символов до или от начала файла, если исходная позиция поиска была
однако это более сложно, так как файл является итератором.Так что составьте список и возьмите random.выбор (если вам нужно много, используйте random.образец):
Это зависит от того, что вы подразумеваете под "слишком большими" накладными расходами. Если возможно сохранение всего файла в памяти, то что-то вроде
будет делать трюк.
хотя я опоздал на четыре года, я думаю, что у меня есть самое быстрое решение. Недавно я написал пакет python под названием linereader, что позволяет манипулировать указателями дескрипторов файлов.
вот простое решение для получения случайной строки с этим пакетом:
первый раз, когда это делается, является худшим, так как linereader должен скомпилировать выходной файл в специальном формате. После этого linereader может получить доступ к любой строке из файл быстро, независимо от размера файла.
если ваш файл очень маленький (достаточно маленький, чтобы поместиться в МБ), то вы можете заменить dopen С copen , и он делает кэшированную запись файла в памяти. Это не только быстрее, но вы получаете количество строк в файле по мере его загрузки в память; это делается для вас. Все, что вам нужно сделать, это создать случайный номер строки. Вот пример кода для этого.
Я просто очень счастлив, потому что я видел кого-то, кто мог бы извлечь выгоду из моего пакета! Жаль погибших ответа, но определенно может быть применен ко многим другим проблемам.
Если вы не хотите читать весь файл, вы можете искать в середине файла, то поиск назад для новой строки, и вызвать readline .
вот скрипт Python3, который делает именно это,
одним из недостатков этого метода является то, что короткие линии имеют меньшую вероятность появления.
найдите случайную позицию, прочитайте строку и отбросьте ее, затем Прочитайте другую строку. Распределение линий не будет нормальным, но это не всегда важно.
вы можете добавить строки в set (), который изменит их порядок случайным образом.
чтобы найти 1-ая строка:
чтобы найти 3-ю строку:
чтобы перечислить все строки в наборе:
Это может быть громоздким, но это работает, я полагаю? (по крайней мере для txt файлов)
он читает каждую строку файла и добавляет ее в список. Затем он выбирает случайную строку из списка. Если вы хотите удалить строку после ее выбора, просто сделайте
надеюсь, что это может помочь, но по крайней мере без дополнительных модулей и импорта (кроме случайных) и относительно легкий.
каков наилучший способ выбрать случайный файл из каталога в Python?
Edit: вот что я делаю:
это особенно плохо, или есть особенно лучший способ?
что касается вашего отредактированного вопроса: во-первых, я предполагаю, что вы знаете риски использования dircache , а также тот факт, что он является устарел с 2.6 и удален в 3.0.
dircache объект в основном неизменяем (после того, как список каталогов кэшируется, он никогда не читается снова), поэтому никакого вреда в параллельных чтениях из него.
кроме этого, я не понимаю, почему вы видите любая проблема с этим решением. Все в порядке.
язык агностик решение:
1) получить общее нет. файлов в указанном каталоге.
2) Выберите случайное число от 0 до [всего нет. файлов - 1].
3) получить список имен файлов в виде подходящей индексированной коллекции или такой.
4) Выберите N-й элемент, где n-случайное число.
Если вы хотите, чтобы каталоги были включены, ответ Юваля А. Иначе:
проблема с большинством приведенных решений заключается в том, что вы загружаете все свои входные данные в память, что может стать проблемой для больших входов/иерархий. Вот решение, адаптированное Поваренная Книга Perl том Кристиансен и Нат Торкингтон. Чтобы получить случайный файл в любом месте под каталогом:
обобщение немного делает удобный скрипт:
независимо от используемого языка, вы можете прочитать все ссылки на файлы в каталоге в datastructure как массив (что-то вроде "listFiles"), получить длину массива. вычислите случайное число в диапазоне от " 0 " до "arrayLength-1" и получите доступ к файлу с определенным индексом. Это должно работать, а не только в python.
Если вы не знаете, какие файлы есть, вам нужно будет получить список, а затем просто выбрать случайный индекс в списке.
вот еще одна попытка:
редактировать: в вопросе теперь упоминается страх перед "расовым состоянием", которое я могу только предположить, является типичной проблемой добавления/удаления файлов, пока вы пытаетесь выбрать случайный файл.
Я не верю, что есть способ обойти это, кроме как держать в имейте в виду, что любая операция ввода-вывода по своей сути "небезопасна", т. е. может завершиться неудачей. Итак, алгоритм для открытия случайно выбранного файла в заданном каталоге должен:
- на самом деле open() выбранный файл и обрабатывать сбой, так как файл больше не может быть там
- вероятно, ограничится заданным количеством попыток, поэтому он не умирает, если каталог пуст или если ни один из файлов не читается
самое простое решение-использовать os.listdir & случайные.выбор nethods
давайте посмотрим на него шаг за шагом : -
1> os.listdir метод возвращает список, содержащий имя записи (файлы) в указанном пути.
2> Этот список передается в качестве параметра случайные.выбор способ которая возвращает случайное имя файла из список.3> имя файла хранится в random_file переменной.
учитывая приложение в реальном времени
вот пример кода python, который будет перемещать случайные файлы из одного каталога в другой
Вы можете проверить весь проект на GitHub Случайный Выбор Файлов
для дополнение ссылка о os.listdir & случайные.выбор способ вы можете обратиться к tutorialspoint узнать python
Многим из нас знакома ситуация, когда компьютер оказывался завален тоннами беспорядочных файлов. Только что вы открывали большой zip-архив, спустя мгновение – файлы повсюду в этой директории, вперемешку с важными документами. Наверняка приходилось мучительно скучно сортировать эту свалку вручную? Чтобы облегчить подобные задачи, мы сейчас погрузимся в «умную» работу с файлами при помощи Python.
Итак, приступим, вооружившись Python версии 3.4 или выше. Сначала пройдемся по модулю OS, а по ходу дела познакомимся еще с несколькими. Всё, что мы будем использовать, доступно в Python «с коробки», так что ничего дополнительно устанавливать не потребуется.
Способ 2
В качестве хитрого способа создать список в одну строку можно использовать генераторы.
Оба варианта сработают, и все ваши файлы будут отсортированы по расширению.
Вот и все. Если вам когда-либо понадобится отсортировать файлы таким образом, вы сэкономите немало времени ?. Код упражнения доступен здесь.
Английский для программистов
Наш телеграм канал с тестами по английскому языку для программистов. Английский это часть карьеры программиста. Поэтому полезно заняться им уже сейчас
Генератор случайных файлов
Создадим папку ManageFiles , а внутри нее еще одну — RandomFiles . Дерево каталогов теперь должно выглядеть вот так:
Чтобы поиграться с файлами, мы сгенерируем их случайным образом в директории RandomFiles . Создайте файл create_random_files.py в папке ManageFiles . Вот что должно получиться:
Готово? Теперь поместите в файл следующий код, и перейдем к его рассмотрению:
Начиная с Python 3.4 мы получили pathlib, нашу маленькую волшебную палочку. Также мы импортируем функцию random для генерации случайных чисел, но ее мы посмотрим в действии чуть ниже.
Сперва создадим список файловых расширений для формирования названий файлов. Не стесняйтесь добавить туда свои варианты.
Далее мы переходим в папку RandomFiles и запускаем цикл. В нем мы просто говорим: возьми каждый элемент list_of_extensions и сделай с ним кое-что во внутреннем цикле 20 раз.
Теперь пришло время для импортированной функции random . Используем ее для производства случайных чисел от 1 до 50. Это просто не очень творческий способ побыстрее дать названия нашим тестовым файлам: к сгенерированному числу добавим расширение файла и получим что-то вроде 23.txt или 14.txt . И так 20 раз для каждого расширения. В итоге образуется беспорядок, достаточный для того, чтобы его было лень сортировать вручную.
Итак, запустим наш генератор хаоса через терминал.
Поздравляю, теперь у нас полная папка неразберихи. Будем распутывать.
В той же директории, где create_random_files.py , создадим файл clean_up.py и поместим туда следующий код.
Способ 1
Для этого импортируем еще две библиотеки: shutil и glob. Первая поможет перемещать файлы, а вторая – находить и систематизировать. Но обо всем по порядку.
Для начала получим список всех файлов в директории.
Здесь мы предполагаем, что у нас нет ни малейшего понятия о том, какие именно файлы лежат в этой папке. Вместо того, чтобы вписывать все расширения вручную и использовать лестницу инструкций if или switch, мы желаем, чтобы программа сама просмотрела каталог и определила, на какие типы можно разделить его содержание. Что, если бы там были файлы с десятками расширений или логи? Вы бы стали описывать их вручную?
Получив список всех файлов, мы заходим в еще один цикл, чтобы извлечь расширения названий.
Сейчас наша переменная our_file выглядит как-нибудь так: 5.docx . Когда разделим ее, получим следующее:
Мы возьмем отсюда второй элемент по индексу [1], то есть .docx . Ведь по индексу [0] у нас располагается 5 .
Таким образом, у нас имеется список всех файловых расширений в папке, в том числе повторяющихся. Чтобы оставить только уникальные элементы, преобразуем его во множество. К примеру, если бы этот список состоял исключительно из .docx , повторяющегося снова и снова, то в set остался бы всего один элемент.
Заметим, что в списке типов файлов каждое расширение содержит . в начале. Если мы назовем так папки на UNIX-системе, то они будут скрытыми, что не входит в наши намерения.
Поэтому, итерируя по нашему множеству, мы заменяем точку на пустую строку. И создаем папку с полученным названием.
Но чтобы переместить файлы, нам все еще нужно расширение .docx .
Этим попросту отбираем все файлы, оканчивающиеся расширением .docx . Заметьте, что в f'*.') нет пробелов.
Символ подстановки * обозначает, что подходит любое имя, если оно заканчивается на .docx . Поскольку мы уже включили точку в поиск, мы используем [1:], что значит «все после первого символа». В нашем примере это docx .
Что дальше? Перемещаем любые файлы с данным расширением в директорию с тем же названием.
Таким образом, как только в цикле создана папка для первого попавшегося файла с данным расширением, все последующие файлы будут отправлены в нее же. Все будет сгруппировано без повторения каталогов.
Читайте также: