从目录中选择随机文件的最佳方法

Posted

技术标签:

【中文标题】从目录中选择随机文件的最佳方法【英文标题】:Best way to choose a random file from a directory 【发布时间】:2009-03-31 14:58:41 【问题描述】:

在 Python 中是什么?

编辑:这是我正在做的:

import os
import random
import dircache

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

这是特别糟糕,还是有特别好的方法?

【问题讨论】:

【参考方案1】:
import os, random
random.choice(os.listdir("C:\\")) #change dir name to whatever

关于您编辑的问题:首先,我假设您知道使用dircache 的风险,以及它是deprecated since 2.6, and removed in 3.0 的事实。

其次,我看不到这里存在任何竞争条件。您的 dircache 对象基本上是不可变的(目录列表被缓存后,它不会再被读取),因此并发读取它不会造成伤害。

除此之外,我不明白为什么您认为此解决方案有任何问题。没关系。

【讨论】:

如何从变量的子文件夹中随机选择 60% 的文件,在第二个变量中随机选择 40% 的文件? 嘿,猜猜我为什么登陆这个页面?twitter.com/isaac32767/status/1380605988990947328【参考方案2】:

如果你想包含目录,Yuval A 的回答。否则:

import os, random

random.choice([x for x in os.listdir("C:\\") if os.path.isfile(os.path.join("C:\\", x))])

【讨论】:

或者如果你想模拟一个通配符:random.choice([x for x in os.listdir("/my/path") if "pattern" in x]).【参考方案3】:

给出的大多数解决方案的问题是您将所有输入加载到内存中,这可能成为大型输入/层次结构的问题。这是由 Tom Christiansen 和 Nat Torkington 改编自 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

【讨论】:

【参考方案4】:

最简单的解决方案是使用 os.listdirrandom.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 上查看整个项目 Random File Picker


os.listdirrandom.choice方法的补充参考可以参考tutorialspoint learn python

os.listdir :- Python listdir() method

random.choice :- Python choice() method


【讨论】:

【参考方案5】:

语言不可知的解决方案:

1) 获取总数。指定目录中的文件。

2) 从 0 到 [total no.文件数 - 1]。

3) 获取文件名列表作为适当索引的集合等。

4) 选择第 n 个元素,其中 n 是随机数。

【讨论】:

类似语言无关:获取目录中的文件列表,并随机选择一个。【参考方案6】:

与所使用的语言无关,您可以将目录中文件的所有引用读入像数组一样的数据结构(类似于“listFiles”),获取数组的长度。计算 '0' 到 'arrayLength-1' 范围内的随机数并访问特定索引处的文件。这应该有效,不仅在 python 中。

【讨论】:

【参考方案7】:

如果您事先不知道那里有哪些文件,则需要获取一个列表,然后在列表中选择一个随机索引。

这是一次尝试:

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]

编辑:现在的问题提到了对“竞争条件”的恐惧,我只能假设这是在您尝试选择的过程中添加/删除文件的典型问题一个随机文件。

除了记住任何 I/O 操作本质上是“不安全的”(即它可能会失败)之外,我认为没有办法解决这个问题。因此,在给定目录中打开随机选择的文件的算法应该:

实际上open()选择的文件,并处理失败,因为该文件可能不再存在 可能会将自身限制为设定的尝试次数,因此如果目录为空或没有文件可读,它不会死

【讨论】:

【参考方案8】:

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()))

【讨论】:

这个答案可以通过解释问题中提出的方法无法解决的问题来改进。

以上是关于从目录中选择随机文件的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

从目录中选择随机文件

从复选框中选择随机答案的最佳方法[重复]

从目录中选择随机文件[重复]

对生成随机输出的代码进行单元测试的最佳方法是啥?

MYSQL 从每个类别中选择一个随机记录

随机森林与Adaboost