0

我正在编写一个脚本来列出目标目录中最大的 20 个文件。获得文件后,我会对大小进行一些数学运算,以应用正确的人类可读的大小信息,即 Kb、Mb、Gb。

然而,这使排序变得混乱。我怎样才能做到这一点,并保持排序顺序不变?

#! /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
4

2 回答 2

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)
于 2012-04-28T21:39:43.603 回答
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
于 2012-04-28T21:59:31.127 回答