Лучший способ выбрать случайный файл из каталога

Как лучше всего выбрать случайный файл из каталога в Python?

Изменить: Вот что я делаю:

import os
import random
import dircache

dir = 'some/directory'
filename = random.choice(dircache.listdir(dir))
path = os.path.join(dir, filename)

Это особенно плохо или есть способ лучше?


person JasonSmith    schedule 31.03.2009    source источник


Ответы (8)


import os, random
random.choice(os.listdir("C:\\")) #change dir name to whatever

Что касается вашего отредактированного вопроса: во-первых, я предполагаю, что вы знаете о рисках использования dircache, а также о том, что это устарело с версии 2.6 и удалено в версии 3.0.

Во-вторых, я не вижу здесь каких-либо условий гонки. Ваш объект dircache в основном неизменяем (после кеширования списка каталогов он больше не читается), поэтому одновременное чтение из него не повредит.

Кроме того, я не понимаю, почему вы видите какие-либо проблемы с этим решением. Это нормально.

person Yuval Adam    schedule 31.03.2009
comment
Как я могу случайным образом выбрать 60% файлов из подпапок в переменной и 40% во второй переменной? - person Aadnan Farooq A; 17.09.2019
comment
Эй, угадайте, почему я попал на эту страницу? twitter.com/isaac32767/status/1380605988990947328 - person Isaac Rabinovitch; 10.04.2021

Если вы хотите, чтобы каталоги были включены, ответ Ювала А. Иначе:

import os, random

random.choice([x for x in os.listdir("C:\\") if os.path.isfile(os.path.join("C:\\", x))])
person mavnn    schedule 31.03.2009
comment
Или, если вы хотите подражать подстановочному знаку: random.choice([x for x in os.listdir("/my/path") if "pattern" in x]). - person Skippy le Grand Gourou; 03.05.2019

Проблема с большинством приведенных решений заключается в том, что вы загружаете весь свой ввод в память, что может стать проблемой для больших входов / иерархий. Вот решение, адаптированное из The Perl Cookbook Тома Кристиансена и Ната Торкингтона. . Чтобы получить случайный файл в любом месте под каталогом:

#! /usr/bin/env python
import os, random
n=0
random.seed();
for root, dirs, files in os.walk('/tmp/foo'):
  for name in files:
    n += 1
    if random.uniform(0, n) < 1:
        rfile=os.path.join(root, name)
print rfile

Небольшое обобщение делает скрипт удобным:

$ cat /tmp/randy.py
#! /usr/bin/env python
import sys, random
random.seed()
n = 1
for line in sys.stdin:
  if random.uniform(0, n) < 1:
      rline=line
  n += 1
sys.stdout.write(rline)

$ /tmp/randy.py < /usr/share/dict/words 
chrysochlore

$ find /tmp/foo -type f | /tmp/randy.py
/tmp/foo/bar
person keithpjolley    schedule 28.01.2017

Самое простое решение - использовать методы os.listdir и random.choice.

random_file=random.choice(os.listdir("Folder_Destination"))

Давайте посмотрим на это шаг за шагом: -

1} os.listdir метод возвращает список, содержащий имена записей (файлов) по указанному пути.

2} Этот список затем передается в качестве параметра методу random.choice, который возвращает случайное имя файла из списка.

3} Имя файла хранится в переменной random_file.


Рассмотрение приложения реального времени

Вот пример кода Python, который перемещает случайные файлы из одного каталога в другой

import os, random, shutil

#Prompting user to enter number of files to select randomly along with directory
source=input("Enter the Source Directory : ")
dest=input("Enter the Destination Directory : ")
no_of_files=int(input("Enter The Number of Files To Select : "))

print("%"*25+"{ Details Of Transfer }"+"%"*25)
print("\n\nList of Files Moved to %s :-"%(dest))

#Using for loop to randomly choose multiple files
for i in range(no_of_files):
    #Variable random_file stores the name of the random file chosen
    random_file=random.choice(os.listdir(source))
    print("%d} %s"%(i+1,random_file))
    source_file="%s\%s"%(source,random_file)
    dest_file=dest
    #"shutil.move" function moves file from one directory to another
    shutil.move(source_file,dest_file)

print("\n\n"+"$"*33+"[ Files Moved Successfully ]"+"$"*33)

Вы можете проверить весь проект на github Инструмент случайного выбора файлов


Дополнительную информацию о методах os.listdir и random.choice вы можете найти в tutorialspoint learn python.

os.listdir: - метод Python listdir ()

random.choice: - метод Python choice ()


person THE_PHOENIX_777_TDW    schedule 01.10.2018

Независимое от языка решение:

1) Получите общее количество файлов в указанном каталоге.

2) Выберите случайное число от 0 до [общее кол-во. файлов - 1].

3) Получите список имен файлов в виде соответствующим образом проиндексированной коллекции или чего-то подобного.

4) Выберите n-й элемент, где n - случайное число.

person karim79    schedule 31.03.2009
comment
Точно так же независимо от языка: получите список файлов в каталоге и выберите один случайным образом. - person Elazar; 07.05.2020

Независимо от используемого языка, вы можете прочитать все ссылки на файлы в каталоге в структуру данных, такую ​​как массив (что-то вроде listFiles), получить длину массива. вычислить случайное число в диапазоне от «0» до «arrayLength-1» и получить доступ к файлу по определенному индексу. Это должно работать не только в python.

person Mork0075    schedule 31.03.2009

Если вы не знаете заранее, какие файлы есть, вам нужно будет получить список, а затем просто выбрать случайный индекс в списке.

Вот одна попытка:

import os
import random

def getRandomFile(path):
  """
  Returns a random filename, chosen among the files of the given path.
  """
  files = os.listdir(path)
  index = random.randrange(0, len(files))
  return files[index]

РЕДАКТИРОВАТЬ: в вопросе упоминается боязнь "состояния гонки", которая, я могу только предположить, является типичной проблемой добавления / удаления файлов, когда вы пытаетесь выбрать случайный файл. .

Я не верю, что есть способ обойти это, кроме как иметь в виду, что любая операция ввода-вывода по своей сути «небезопасна», то есть может потерпеть неудачу. Итак, алгоритм открытия случайно выбранного файла в заданном каталоге должен:

  • На самом деле open() выбранный файл и обработать сбой, так как файл может больше не существовать
  • Вероятно, ограничьте себя установленным количеством попыток, поэтому он не умирает, если каталог пуст или если ни один из файлов не доступен для чтения
person unwind    schedule 31.03.2009

Python 3 имеет модуль pathlib, который можно использовать для анализа файлов и каталоги более объектно-ориентированным способом:

from random import choice
from pathlib import Path

path: Path = Path()
# The Path.iterdir method returns a generator, so we must convert it to a list
# before passing it to random.choice, which expects an iterable.
random_path = choice(list(path.iterdir()))
person Chris Norman    schedule 22.12.2020
comment
Этот ответ можно улучшить, объяснив, какую проблему он решает, но не решает подход, представленный в вопросе. - person Nathan; 22.12.2020
comment
Хорошо, спасибо за предупреждение. - person Chris Norman; 23.12.2020