2009-03-31 23 views
16

Pythonのディレクトリからランダムなファイルを選択する最良の方法は何ですか?ディレクトリからランダムなファイルを選択する最も良い方法

編集:ここではは私が何をやっているされています

import os 
import random 
import dircache 

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

が、これは特に悪いですか、特に良い方法はありますか?

+0

申し訳ありませんがみんな、私が誤って提出しました。しかし、あまり変わってはいけません。 – JasonSmith

+0

競争条件の問題を明確にすることはできますか?私はあなたが間違ったウィンドウを選択してファイルを開くことを意味すると思っています(例えば、誰かがそれを選択して開こうとする間にそのファイルを削除するかもしれませんが、これを明示的に述べる価値があります)。 – Brian

+0

複数のプロセスがこれを同時に実行するため競合状態ですか?または、ライターがファイルを作成しているため、競合状態が発生しますか?これを選択しているリーダーですか? –

答えて

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

読めるしない場合、それは死なないように:まず、Iあなたはdircacheを使用するリスクと、それがdeprecated since 2.6, and removed in 3.0であることを知っています。

第2に、私はどこに競合状態が存在するかわかりません。 dircacheオブジェクトは基本的に不変です(ディレクトリリストをキャッシュした後は、それを再度読み取ることはできません)。

それ以外は、なぜこの解決策に問題があるのか​​わかりません。それは結構です。

+1

dircacheは推奨されていません。 –

1

使用する言語から独立して、ディレクトリ内のファイルへのすべての参照を配列(「listFiles」など)のようなデータ構造に読み込み、配列の長さを取得できます。 '0'から 'arrayLength-1'の範囲の乱数を計算し、特定のインデックスのファイルにアクセスします。これは、Pythonだけでなく、うまくいくはずです。

1

どのファイルが手元にあるのかわからない場合は、リストを取得してから、リスト内のランダムなインデックスを選択する必要があります。

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] 

EDIT

は、ここに1つの試みだ質問は今、私はファイルだけの典型的な問題は、あなたがしている間、削除/追加されていると仮定することができ、「競合状態」の恐怖に言及しますランダムなファイルを選択しようとしています。

I/O操作が本質的に「安全でない」、つまり失敗する可能性があることを覚えておいてください。だから、与えられたディレクトリ内のランダムに選択されたファイルを開くためのアルゴリズムべきである:

  • 実際open()ファイル選択、およびファイルは、もはや
  • がないかもしれないので、失敗を扱うには、おそらくセットに自分自身を制限します試行回数、ディレクトリが空の場合、またはファイルのどれもが編集した質問について
+0

ええ、それについて知らなかった、別の答えでそれを見た。知っておいて、ありがとう! – unwind

4

言語に依存しないソリューション:

1)合計を取得します。指定されたディレクトリにあるファイルの数。

2)0〜[全数]の乱数を選択します。のファイル - 1]。

3)適切にインデックスされたコレクションなどのファイル名のリストを取得します。

4)n番目の要素を選択します.nは乱数です。

4

ディレクトリを含めたい場合は、Yuval Aの答えです。それ以外の場合:

import os, random 

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

大きな入力/階層の問題になることができますが、メモリにすべての入力をロードされた特定のソリューションのほとんどの問題点。ここには、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=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 
関連する問題