Python:在写入csv时连接和格式化字符串/浮点数

时间:2013-06-01 06:05:29

标签: python csv formatting

我有一个变量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
  3. 但是,我需要格式化输出,以便所有浮点数只有2位小数,并将USD连接到第二和第三列值的前面,并在最后一列值的末尾添加一个“%”符号。虽然我可以迭代'compareout'并替换最后两个colums,如此...

    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个项目。 ..

    我用Google搜索了大约一个小时,似乎无法找到足够的信息来确定csv.writerow()函数是否允许在编写时进行格式化,而且我已经用完了方法。如果有人能给我一些想法,我会非常感激......

2 个答案:

答案 0 :(得分: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)

请注意,在sorted列表中调用两次compareout将花费两倍的时间,而使用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),但在其他情况下这是不可能的。)

答案 1 :(得分:0)

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

的csv文件

sorted(output,key = itemgetter(0,1))#例如,使用operator.itemgetter()

按列0然后1排序列表对象

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

因为你想要为每个输出文件只写10个项目,请查看csvreader.line_num或使用带有csvreader的循环。 next ()