将csv输入文件打印到列/行表中

时间:2015-10-19 23:29:57

标签: python csv

我正在尝试编写一个程序(除其他外),将输入文件(' table1.txt')打印成下面所示的格式。

enter image description here

其中diff是每行第3和第4个值之间的差异。

我认为我已经找到了基本想法,我尝试过:

f = open("table1.txt",'r')

for aline in f:
    values = aline.split(',')
    print('Team:',values[0],', Points:',values[1],', Diff:',values[2]-values[3],'Goals:',values[2]) 

f.close()

但它会导致操作数类型错误。我想我只需要改变迭代文件中项目的方式,但我不知道如何。

3 个答案:

答案 0 :(得分:6)

你绝对应该使用csv模块。它允许您遍历行和值(基本上构建一个奇特的#34;列表列表")。 csv还有一个DictWriter对象可以很好地将这些数据吐入文件,但实际显示它有点不同。让我们先看看构建csv。

import csv
import operator

with open('path/to/file.txt') as inf,
     open('path/to/output.csv', 'wb') as outf:
    reader = sorted(csv.reader(inf), key=operator.itemgetter(1)
    # sort the original data by the `points` column

    header = ['Team', 'Points', 'Diff', 'Goals']
    writer = csv.DictWriter(outf, fieldnames=header)

    writer.writeheader()  # writes in the fieldnames
    for row in reader:
        if not len(row) == 4:
            break  # This is probably not a useful row
        teamname, points, home_g, away_g = row
        writer.writerow({'Team': teamname,
                         'Points': points,
                         'Diff': home_g - away_g,
                         'Goals': "{:>2} : {:2}".format(home_g, away_g)
                         })

这应该为您提供一个csv文件(path/to/output.csv),其中包含您请求的格式的数据。此时,只需拉取数据并运行print语句即可显示它。我们可以使用字符串模板来很好地完成这项工作。

import itertools

row_template = """\
{{0:{idx_length}}}{{<1:{teamname_length}}}{{>2:{point_length}}}{{>3:{diff_length}}}{{=4:{goals_length}}}"""

with open('path/to/output.csv') as inf:  # same filename we used before
    reader = csv.reader(inf)  # no need to sort it this time!
    pre_process, reader = itertools.tee(reader)
    # we need to get max lengths for each column to build our table, so
    # we will need to iterate through twice!
    columns = zip(*pre_process)  # this is magic
    col_widths = {k: len(max(col, key=len)) for k,col in zip(
        ['teamname_length', 'point_length', 'diff_length', 'goals_length'],
        columns)}

值得停下来看看这个魔法。除了注意到它将行列变成行列之外,我不会进入columns = zip(*pre_process)魔法习语。换句话说

zip(*[[1, 2, 3],
      [4, 5, 6],
      [7, 8, 9]])

变为

     [[1, 4, 7],
      [2, 5, 8],
      [3, 6, 9]]

之后我们只是使用字典理解来构建{'team_length': value, 'point_length': ...}等我们可以提供给我们的模板以使字段宽度合适。

但是等等!

我们还需要该词典中的idx_length!我们只能通过len(rows) // 10计算出来。不幸的是,我们已经耗尽了我们的迭代器,而且我们还没有更多的数据。这需要重新设计!我实际上并没有很好地计划好这一点,但在编码过程中看到这些事情是如何发生的那样很好。

import itertools

row_template = """\
{{0:{idx_length}}}{{<1:{teamname_length}}}{{>2:{point_length}}}{{>3:{diff_length}}}{{=4:{goals_length}}}"""

with open('path/to/output.csv') as inf:  # same filename we used before
    reader = csv.reader(inf)
    pre_process, reader = itertools.tee(reader)

    # fun with pre-processing for field length!
    columns = zip(*pre_process)

    keys = ['teamname_length', 'point_length', 'diff_length', 'goals_length']
    col_widths = {k:0 for k in keys}
    for key, column in zip(keys, columns):
        col_widths['idx_length'] = max([col_widths['idx_length'], len(column) // 10 + 1])
        col_widths[key] = max((col_widths[key],max([len(c) for c in column)))

    col_widths['idx_length'] += 1  # to account for the trailing period

    row_format = row_template.format(**col_widths)
    # puts those field widths in place

    header = next(reader)
    print(row_format("", *header))  # no number in the header!
    for idx, row in enumerate(reader, start=1):  # let's do it!
        print(row_format("{}.".format(idx), *row))

包括电池(几乎)

但是,不要忘记Python有广泛的第三方模块选择。一个人完全符合你的需要。 tabulate将获取格式良好的表格数据并为其喷出漂亮的ascii表格。正是你要做的事情

从命令行的pypi安装

$ pip install tabulate

然后导入您的显示文件并打印。

import tabulate

with open('path/to/output.csv') as inf:
    print(tabulate(inf, headers="firstrow"))

或直接从输入跳到打印:

import csv
import operator
import tabulate

with open('path/to/file.txt') as inf:
    reader = sorted(csv.reader(inf), key=operator.itemgetter(1))
    headers = next(reader)
    print(tabulate([(row[0], row[1], row[2]-row[3],
                     "{:>2} : {:2}".format(row[2], row[3])) for row in reader],
                   headers=headers))

答案 1 :(得分:2)

在执行减法时尝试将值[2]和值[3]转换为int:

', Diff:', int(values[2])-int(values[3])

答案 2 :(得分:2)

刚试过,如果加载txt文件,CSV模块就不在乎了。

我会使用with open ... as方法,因为它更干净,之后你不必关闭f。

import csv

with open("importCSV.txt",'r') as f:
    rowReader = csv.reader(f, delimiter=',')
    #next(rowReader)  -use this if your txt file has a header strings as column names
    for values in rowReader:
        print'Team:',values[0],', Points:',values[1],', Diff:',int(values[2])-int(values[3]),'Goals:',values[2]