【发布时间】:2020-04-25 00:55:18
【问题描述】:
我有一个包含大量文件的目录。我不想将所有文件名都保存在内存中,但我想使用生成器随机获取这些文件的子集。
我可以使用帖子“Best way to choose a random file from a directory”中的信息来做到这一点,但我想确保我的生成器不会两次返回同一个文件。所以最终在运行生成器(它将返回批次)之后,我会循环浏览目录中的整个文件列表。
我能想到的方法仍然会创建一个文件列表来进行比较(创建一个已使用文件名的列表,如果不在列表中则返回),并且生成器产生结果的次数越多,执行时间就越长。
有没有办法,如果我创建一个与目录中文件数相等的数字数组,当我从数组中随机弹出一个值时,我可以在那个位置获取文件? (我认为这会比字符串数组占用更少的内存)
从当前的 cmets 我有以下代码:
def GetRandomFileListGenerator(self, path):
fileList = [f for f in listdir(path) if isfile(join(path, f))]
random.shuffle(fileList)
while(self.batchSize < len(fileList)):
yield fileList[:self.batchSize]
fileList = fileList[self.batchSize:]
【问题讨论】:
-
“我认为这将比字符串数组占用更少的内存”。好吧,定义“显着减少”。在我的机器上,一个整数是 14 个字节,一个字符串是 25+len(the_string) 个字节,所以对于有十几个字符左右的字符串,使用整数列表只会将内存使用量减少三倍。除非您已经对系统的限制感到紧张,否则任何低于一个数量级的节省对我来说似乎都不值得。
-
如果您放弃整数数组要求,那么从集合中选择 N 个唯一元素很容易 - 只需调用
random.sample(the_filenames, N) -
至于“选择随机索引”:请注意,通常不能保证目录中的文件是有序的!
-
没问题,拨打
random.sample(the_filenames, len(the_filenames))即可。然后它将遍历每个文件名一次,然后变得筋疲力尽。或者,在迭代之前调用列表上的random.shuffle一次。 -
如果文件被添加/删除到目录而生成器正在生成路径会发生什么?
标签: python random generator file-listing