2015-10-19 157 views
1

我正在嘗試編寫一個程序(其中包括),將輸入文件('table1.txt')打印到下面的格式中。將csv輸入文件打印到列/行的表中

enter image description here

當DIFF是第三和每行的第四值之間的差。

我覺得我有基本的想法想通了,我想這樣做:

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() 

但它會導致操作類型的錯誤。我想我只需要改變我遍歷文件中的項目的方式,但我不知道如何。

+0

'值[2] - 值[3]'值是字符串的列表。 – sam

+0

如果您更改問題文本,那麼提供的答案對未來的讀者來說不會有意義。如果您有其他問題,而不是您之前指定的其他問題,請創建一個新問題 – sam

+0

請不要修改您的問題,使其使答案失效。 – Matt

回答

2

你應該明確地使用csv這個模塊。它允許你遍歷行和值(基本上構建一個花哨的「列表清單」)。 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': ...}等,我們可以輸入我們templater使字段寬度大小合適。

但是等一下!

我們還需要該字典中的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)) 
2

執行減法時,試圖鑄造值[2]和值[3]轉換成int:

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

+0

謝謝。我最初做了:',Diff:',int(值[2] - 值[3]),但你的作品。 – Newbie

+0

np ..如果你int(str-str)那麼你將減法運算的結果轉換爲int ..哪個不會工作,因爲你不能減去字符串 –

+0

關於如何將csv打印成列和行的任何提示格式如上所示? – Newbie

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] 
+0

我並不瘋狂,對吧?這並不像他預期的輸出 –

+0

我不打算爲他/她解決它,我試圖演示如何使用'open。as'和CSV模塊。我不認爲SO是讓人們編寫代碼的地方。 – JasTonAChair