2013-11-27 59 views
6

我在編寫一個程序,它需要一個命令行參數,掃描參數提供的目錄樹並創建目錄中每個文件的列表,然後對其進行排序通過文件的長度。從目錄參數中獲取文件,按大小排序

我沒有太大的腳本傢伙 - 但這是我有什麼,它不工作:

import sys 
import os 
from os.path import getsize 

file_list = [] 

#Get dirpath 
dirpath = os.path.abspath(sys.argv[0]) 
if os.path.isdir(dirpath): 
    #Get all entries in the directory 
    for root, dirs, files in os.walk(dirpath): 
     for name in files: 
      file_list.append(name) 
     file_list = sorted(file_list, key=getsize) 
     for item in file_list: 
      sys.stdout.write(str(file) + '\n') 

else: 
    print "not found" 

任何人都可以點我在正確的方向?

+0

我建議閱讀功能['幫助Ø s.walk'](http://docs.python.org/2/library/os.html#os.walk)。這似乎是處理目錄樹的正確選擇。如果你看看這個函數的例子,你會看到,你正在一個很好的方式... – koffein

+0

我認爲你最後一行之前是沒有必要的。實際上這行是導致錯誤... – koffein

+0

@koffein我已經更新了我的代碼,但它仍然給我一個錯誤。 –

回答

6

希望這個功能能幫助你(我使用Python 2.7):

import os  

def get_files_by_file_size(dirname, reverse=False): 
    """ Return list of file paths in directory sorted by file size """ 

    # Get list of files 
    filepaths = [] 
    for basename in os.listdir(dirname): 
     filename = os.path.join(dirname, basename) 
     if os.path.isfile(filename): 
      filepaths.append(filename) 

    # Re-populate list with filename, size tuples 
    for i in xrange(len(filepaths)): 
     filepaths[i] = (filepaths[i], os.path.getsize(filepaths[i])) 

    # Sort list by file size 
    # If reverse=True sort from largest to smallest 
    # If reverse=False sort from smallest to largest 
    filepaths.sort(key=lambda filename: filename[1], reverse=reverse) 

    # Re-populate list with just filenames 
    for i in xrange(len(filepaths)): 
     filepaths[i] = filepaths[i][0] 

    return filepaths 
+1

''''''''''''''我讀了幾次,我發現它可行,但我也注意到,你還沒有發現所有的小東西,使你的Python代碼更漂亮並可讀。我希望你能感謝一些建議: 每當你認爲你需要爲範圍(len(some_list))寫''i,使用['enumerate'](http://docs.python.org/2/library/functions .html#enumerate)來代替。 如果你想重新填充一個列表,放棄你的「數組思路」,嘗試使用類似這樣的東西:'lst = [do_something(entry)in entry in lst]'... – koffein

+2

但是,如果生成列表中,您想要重新填充而不需要進一步使用,請考慮使用生成器。所以你不必一遍又一遍地重複列表...節省內存,時間... 如果您已經厭倦了閱讀本文,請觀看此視頻......經過多年Python編程後,我的嘴巴張開了! [轉化代碼爲美麗的,地道的Python(https://www.youtube.com/watch?v=OSGv2VnC0go) – koffein

+0

'dirname'是在'os.path'功能的保留名稱,你不應該使用它作爲腳本中的變量名稱。該功能很棒BTW! – Gabriel

0

您正在提取命令,而不是第一個參數argv[0];使用argv[1]爲:

dirpath = sys.argv[1] # argv[0] contains the command itself. 

出於性能方面的原因,我建議你預取文件的大小,而不是分選過程中多次詢問OS關於同一文件的大小(以Koffein所建議的,os.walk是必經之路去):

files_list = [] 
for path, dirs, files in os.walk(dirpath)): 
    files_list.extend([(os.path.join(path, file), getsize(os.path.join(path, file))) for file in files]) 

假設你不需要無序列表中,我們將使用就地sort()方法:

files_list.sort(key=operator.itemgetter(1)) 
+0

'files'-list只是文件名的列表,不是嗎?我認爲你必須加入''''''''''''''' – koffein

5

這是一種使用生成器的方法。應該是大量文件的速度更快...

這兩個示例的開頭:

import os, operator, sys 
dirpath = os.path.abspath(sys.argv[0]) 
# make a generator for all file paths within dirpath 
all_files = (os.path.join(basedir, filename) for basedir, dirs, files in os.walk(dirpath) for filename in files ) 

如果你只是想沒有大小的文件的列表,你可以使用這個:

sorted_files = sorted(all_files, key = os.path.getsize) 

但是如果你想在列表中的文件和路徑,您可以使用此:

# make a generator for tuples of file path and size: ('/Path/to/the.file', 1024) 
files_and_sizes = ((path, os.path.getsize(path)) for path in all_files) 
sorted_files_with_size = sorted(files_and_sizes, key = operator.itemgetter(1)) 
+0

使用'sorted_files_with_size.reverse()'首先查看最大的文件。這非常快,對於快速瞭解哪些文件佔用空間很有用。 –

相關問題