【问题标题】: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)

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

【问题讨论】:

    标签: python file random


    【解决方案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 对象基本上是不可变的(目录列表被缓存后,它不会再被读取),因此并发读取它不会造成伤害。

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

    【讨论】:

    【解决方案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()))
            

            【讨论】:

            • 这个答案可以通过解释问题中提出的方法无法解决的问题来改进。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-01-30
            • 2010-09-13
            • 2020-08-01
            • 1970-01-01
            • 1970-01-01
            • 2017-12-16
            相关资源
            最近更新 更多