2012-04-28 5 views
0

Я пишу сценарий, чтобы перечислить 20 самых больших файлов в целевом каталоге. Как только у меня есть файлы, я выполняю некоторую математику по размеру, чтобы применить правильную информацию для считывания с человека, то есть Kb, Mb, Gb.Как вы берете данные из сортировки Python и выполняете некоторую математику на кортеже, не испортив порядок сортировки?

Это, однако, приводит к нарушению порядка. Как я могу это сделать и сохранить порядок сортировки неповрежденным?

#! /usr/bin/env python 

import operator, os, sys 

args = sys.argv 
if len(args) != 2: 
    print "You must one enter one directory as an argument." 
    sys.exit(1) 
else: 
    target = args[1] 

data = {} 
for root, dirs, files in os.walk(target): 
    for name in files:  
     filename = os.path.join(root, name) 
     if os.path.exists(filename): 
      size = float(os.path.getsize(filename)) 
      data[filename] = size 

sorted_data = sorted(data.iteritems(), key=operator.itemgetter(1), reverse=True) 
total = str(len(sorted_data)) 

while len(sorted_data) > 20: 
    sorted_data.pop() 

final_data = {} 
for name in sorted_data: 
    size = str(name[1]) 
    if size >= 1024: 
     size = round(float(size)/1024, 2) 
     if size >= 1024: 
      size = round(size/1024, 2) 
      if size >= 1024: 
       size = round(size/1024, 2) 
       size = str(size) + "Gb" 
      else: 
       size = str(size) + "Mb" 
    else: 
     size = str(size) + "Kb" 
    final_data[name] = size 

print "The 20 largest files are:\n" 
for name in final_data: 
    print str(final_data[name]) + " " + str(name) 
print "\nThere are a total of " + total + " files located in " + target 
+0

Вы помещаете отсортированные данные в новый словарь 'final_data', который не предназначен для последовательностей – daniel

ответ

2

Ваша проблема заключается в том, что вы создаете совершенно новый словарь для хранения измененных файлов. Поскольку этот словарь не содержит никакой информации о размерах файла и потому, что словари не хранят свою информацию в каком-либо фиксированном порядке, вы теряете свой порядок сортировки. Но его легко восстановить; просто перебирайте sorted_data вместо final_data, используя final_data для доступа к размерам для чтения человеком. Так что-то вроде этого:

for filename, size in sorted_data: 
    print filename, final_data[filename] 

Но еще лучше было бы поставить читаемую строку генерации кода в функцию!

def human_readable_size(size): 
    # logic to convert size 
    return hr_size 

Теперь вы даже не должны создать словарь:

for filename, size in sorted_data: 
    print filename, human_readable_size(size) 
+0

Спасибо !!! Окончательный оператор печати: для имени файла в sorted_data: print str (final_data [имя_файла [0]]) + "" + str (имя файла [0]) – Josh

+0

Отличное решение, переключается на функциональную версию и отлично работает. – Josh

0

Я знаю, что вы уже получили решение, я просто скучно, и хотел бы видеть, если я мог бы очистить вашу логику еще немного. Вот упрощенная версия вашего кода.

Я бы сказал, действительно, просто не беспокойтесь о диктофонах, они здесь не приносят никакой пользы.

import operator, os, sys 

if len(sys.argv) != 2: 
    sys.exit(1) 

target = sys.argv[1] 

vals = [] 
for root, dirs, files in os.walk(target): 
    names = (os.path.join(root, name) for name in files) 
    vals.extend([ (name, float(os.path.getsize(name))) 
       for name in names if os.path.exists(name)]) 

vals = sorted(vals, key=operator.itemgetter(1), reverse=True) 

converted = [] 
for name, size in vals[0:20]: 
    if size >= 1024*1024*1024: 
    unit = "Gb" 
    size /= 1024*1024*1024 
    elif size >= 1024*1024: 
    unit = "Mb" 
    size /= 1024*1024 
    elif size >= 1024: 
    unit = "Kb" 
    size /= 1024 
    else: 
    unit = "b" 
    converted.append((name, "%.2f"%size + unit)) 

for name, size in converted: 
    print size + " " + name