2012-08-29 12 views
7

Czy można uzyskać częściową listę katalogów?Częściowa lista katalogów

W Pythonie, mam proces, który próbuje uzyskać os.listdir katalogu zawierającego> 100 000 plików i trwa to wieczność. Chciałbym móc, powiedzmy, szybko uzyskać listę pierwszych 1000 plików.

Jak mogę to osiągnąć?

+4

Może to być przydatne: http://www.olark.com/spw/2011/08/you-can-list-a-directory- with-8-million-files-but-not-withls/ – Kev

+0

Schludny! Nie wiedziałem o tym. –

+1

Czy kolejność jest ważna? –

Odpowiedz

3

znalazłem rozwiązanie, które daje mi losową kolejność plików :) (przynajmniej nie widzę wzór)

Najpierw znalazłem this post in the python maillist. Są 3 załączone pliki, które musisz skopiować na dysk (opendir.pyx, setup.py, test.py). Następnie potrzebujesz pakietu Pythona Pyrex, aby skompilować plik opendir.pyx z wpisu. Miałem problemy z instalacją Pyrex i odkryłem, że muszę zainstalować python-dev przez apt-get. Następnie zainstalowałem pakiet opendir z trzech wyżej wymienionych plików za pomocą python setup.py install. Plik test.py zawiera przykłady, jak z niego korzystać.

Następnie zainteresowałem się tym, o ile szybsze będzie to rozwiązanie niż przy użyciu os.listdir i utworzyłem 200000 plików z następującym małym skoroszytem.

for((i=0; i<200000; i++)) 
do 
    touch $i 
done 

Poniższy skrypt jest mój punkt odniesienia uruchomiony w katalogu, w którym po prostu stworzył pliki:

from opendir import opendir 
from timeit import Timer 
import os 

def list_first_fast(i): 
    d=opendir(".") 
    filenames=[] 
    for _ in range(i): 
     name = d.read() 
     if not name: 
      break 
     filenames.append(name) 
    return filenames 

def list_first_slow(i): 
    return os.listdir(".")[:i] 

if __name__ == '__main__': 
    t1 = Timer("list_first_fast(100)", "from __main__ import list_first_fast") 
    t2 = Timer("list_first_slow(100)", "from __main__ import list_first_slow") 
    print "With opendir: ", t1.repeat(5, 100) 
    print "With os.list: ", t2.repeat(5, 100) 

Wyjście na moim systemie to:

With opendir: [0.045053958892822266, 0.04376697540283203, 0.0437769889831543, 0.04387712478637695, 0.04404592514038086] 
With os.list: [9.50291895866394, 9.567682027816772, 9.865844964981079, 13.486984968185425, 9.51977801322937] 

Jak widać I uzyskałem przyspieszenie o wartości 200, zwracając listę 100 nazw plików z 200000, to całkiem miłe :).

Mam nadzieję, że jest to cel, który chcesz osiągnąć.

+0

+1: interesujące, ale wolałbym mieć bardziej standardowe rozwiązanie. – jldupont