Лучший способ выбрать случайный файл из каталога - PullRequest
27 голосов
/ 31 марта 2009

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

Редактировать: Вот что я делаю:

import os
import random
import dircache

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

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

Ответы [ 7 ]

57 голосов
/ 31 марта 2009
import os, random
random.choice(os.listdir("C:\\")) #change dir name to whatever

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

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

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

6 голосов
/ 31 марта 2009

Если вы хотите, чтобы каталоги были включены, ответ Ювала А. В противном случае:

import os, random

random.choice([x for x in os.listdir("C:\\") if os.path.isfile(os.path.join("C:\\", x))])
4 голосов
/ 28 января 2017

Проблема с большинством данных решений заключается в том, что вы загружаете все свои данные в память, что может стать проблемой для больших входов / иерархий. Вот решение, адаптированное из 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=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=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
4 голосов
/ 31 марта 2009

Решение, не зависящее от языка:

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

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

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

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

1 голос
/ 01 октября 2018

Самое простое решение - использовать 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 ()


1 голос
/ 31 марта 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() выбранный файл и обрабатывает ошибку, так как файл может больше не быть
  • Вероятно, ограничьте себя заданным количеством попыток, чтобы он не умер, если каталог пуст или ни один из файлов не доступен для чтения
1 голос
/ 31 марта 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...