2009-03-31 4 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 

읽을 수없는 경우 : 첫째, 당신은 dircache을 사용할 때의 위험성과 그것이 deprecated since 2.6, and removed in 3.0이라는 사실을 알고 계십니까?

두 번째로, 여기서 어떤 경쟁 조건이 존재하는지는 알 수 없습니다. dircache 개체는 기본적으로 변경할 수 없으며 (디렉터리 목록이 캐시 된 후에는 다시 읽지 않습니다.) 동시 읽기에는 아무런 해가 없습니다.

그 외에도이 솔루션에 문제가있는 이유를 알 수 없습니다. 그것은 괜찮습니다.

+1

dircache가 사용되지 않는다는 언급에 감사드립니다. –

1

사용 된 언어와 별개로 디렉토리의 파일에 대한 모든 참조를 배열 ('listFiles'와 같은)과 같은 데이터 구조로 읽을 수 있으며 배열의 길이를 가져올 수 있습니다. '0'에서 'arrayLength-1'범위의 난수를 계산하고 특정 색인의 파일에 액세스하십시오. 이것은 파이썬 에서뿐만 아니라, 작동합니다.

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] 

편집 :

여기에 하나 개의 시도의 문제는 지금은 파일 만의 전형적인 문제는 당신이 동안 제거/추가되고 수락 할 수있는 "경쟁 조건"의 두려움을 언급 임의의 파일을 선택하려고합니다.

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 
관련 문제