2

我有一个compareout存储嵌套数据列表的变量:

compareout = [...
[Guyana,951.723423,1037.123424,28.476757,2.991234],
[Bolivia,936.123420,1065.8234236,43.25123,4.62],
[Philippines,925.52342342,1119.62342341,64.70234234,6.991234123],
[Congo (Rep.),907.22342343,1657.52342349,250.1242342,27.571234123],
...]

我试图:

  1. 按第二列升序排序,将此排序列表的前 10 项写入 .csv
  2. 按第二列降序排序,将前 10 个项目排序列表写入第二个 .csv

但是,我需要格式化输出,使所有浮点数只有 2 个小数位,并将 USD 连接到第二和第三列值的前面,并在最后一列值的末尾添加一个 '%' 符号。虽然我可以迭代'compareout'并像这样替换最后两个列......

for line in compareout:
    avgyrincr = (float(line[2])-float(line[1]))/3
    percent = (avgyrincr/float(line[1])) * 100
    line.append("%.2f" % avgyrincr)
    line.append("%.2f%%" % percent)

我不能做一些简单的事情,比如:

for line in ascending:
    line[1] = "USD %.2f" % line[1]
    line[2] = "USD %.2f" % line[2]

因为这不允许排序。目前,在我第一次对数据进行排序并将其写入第一个文件之后,我立即出现了上面的代码,但当然我不能按降序排序......我也对如何指定只写 10 个项目感到困惑。 ..

我已经用谷歌搜索了大约一个小时,似乎无法找到关于 csv.writerow() 函数是否允许在写入时进行格式化的足够信息,而且我已经用完了方法。如果有人能给我一些想法,我将不胜感激......

4

2 回答 2

2

您可以编写一个format函数,从列表中获取一个项目并返回格式化的行。就像是:

def format_row(row):
    result = row[:]   #make a copy of the row
    # format should be preferred over %.
    # Also, you don't have to escape the %.
    result[1] = "USD {:.2f}".format(result[1])
    result[2] = "USD {:.2f}".format(result[2])
    # do whatever else you have to do for a single row
    return result

之后,您可以执行以下操作:

sorted_values = sorted(the_values, key=lambda x: x[1])   #sort by second column
formatted_lines = (format_row(row) for row in sorted_values[:10])
for line in formatted_lines:
    writer.writerow(line)

#[-10:] -> take last 10 elements, [::-1] reverse the order
other_lines = (format_row(row) for row in sorted_values[-10:][::-1])
for line in other_lines:
    writer.writerow(line)

请注意,sortedcompareout列表上调用两次将花费两倍的时间,而使用sorted_values[-10:][::-1]则需要恒定的时间,因此效率更高。如果您仍想使用两种,我建议您执行以下操作:

sorted_values = sorted(the_values, key=lambda x: x[1])   #sort by second column
# ...
#use sorted_values, instead of the_values
sorted_values.sort(key=lambda x: x[1], reverse=True)
# ...

即调用.sort已经排序的值。列表的排序算法在处理部分排序的数据时非常聪明,因此上面的代码将O(nlogn)用于第一次排序,仅O(n)用于第二次:

>>> import random
>>> L = [random.randint(0, 1000) for _ in range(10000)]
>>> import timeit
>>> timeit.timeit('sorted(L)', 'from __main__ import L', number=100)
0.2509651184082031
>>> timeit.timeit('sorted(L)', 'from __main__ import L', number=100)
0.2547318935394287
>>> L.sort()
>>> timeit.timeit('sorted(L, reverse=True)', 'from __main__ import L', number=100)
0.11794304847717285
>>> timeit.timeit('sorted(L, reverse=True)', 'from __main__ import L', number=100)
0.11488604545593262

(在这个简单的示例中,您可以使用reversed(L),但在其他情况下这是不可能的)。

于 2013-06-01T06:26:33.180 回答
0

考虑创建两个不同的列表对象;相应地对它们进行排序,然后将每行 writerow() 分别放入 csv 文件中

sorted(output,key=itemgetter(0,1)) # 例如,使用 operator.itemgetter() 按列 0 和 1 对列表对象进行排序

尝试将 reverse=True 添加到上述 sorted () 函数以进行降序排序

由于您只想为每个输出文件 writerow() 10 个项目,请查看 csvreader.line_num 或使用带有 csvreader 的循环。下一个()

于 2013-06-01T06:58:47.087 回答