2011-04-09 122 views
0

Write a program which reads a text file called input.txt which contains an arbitrary number of lines of the form ", " then records this information using a dictionary, and finally outputs to the screen a list of countries represented in the file and the number of cities contained.Python-文件解析

例如,如果input.txt中含有下列:

New York, US 
Angers, France 
Los Angeles, US 
Pau, France 
Dunkerque, France 
Mecca, Saudi Arabia 

方案將輸出下面(在一些順序):

Saudi Arabia : 1 
US : 2 
France : 3 

我的代碼:

from os import dirname 

def parseFile(filename, envin, envout = {}): 
    exec "from sys import path" in envin 
    exec "path.append(\"" + dirname(filename) + "\")" in envin 
    envin.pop("path") 
    lines = open(filename, 'r').read() 
    exec lines in envin 
    returndict = {} 
    for key in envout: 
     returndict[key] = envin[key] 
    return returndict 

我得到一個語法錯誤:無效語法... wh我使用我的文件名 我用文件名input.txt

+0

您忘了發佈迄今爲止編寫的代碼,問題,以及您如何嘗試/無法解決問題。 *然後*,有人可能會幫助你。 – mdm 2011-04-09 16:11:13

+0

那麼,你到目前爲止嘗試過什麼? – 2011-04-09 16:11:36

+0

你是怎麼調用'parseFile()'和你看到的語法錯誤是什麼? – Johnsyweb 2011-04-09 16:24:47

回答

1

我會使用defaultdict加上一個列表來維護信息的結構。 因此可以派生出更多的統計數據。

import collections 

def parse_cities(filepath): 
    countries_cities_map = collections.defaultdict(list) 
    with open(filepath) as fd: 
     for line in fd: 
      values = line.strip().split(',') 
      if len(values) == 2: 
       city, country = values 
       countries_cities_map[country].append(city) 
    return countries_cities_map 

def format_cities_per_country(countries_cities_map): 
    for country, cities in countries_cities_map.iteritems(): 
     print " {ncities} Cities found in {country} country".format(country=country, ncities = len(cities)) 


if __name__ == '__main__': 
    import sys 
    filepath = sys.argv[1] 
    format_cities_per_country(parse_cities(filepath)) 
4

我不明白你在做什麼,所以我不能解釋如何解決它。特別是,您爲什麼要輸入文件的行?爲什麼寫exec "foo"而不是foo?我想你應該回到一個基本的Python教程...

無論如何,你需要做的是:使用

  • open文件的完整路徑
  • for line in file:過程中的線,並將其存儲在字典中
  • 返回字典

就是這樣,沒有exec參與。

1
import collections 

def readFile(fname): 
    with open(fname) as inf: 
     return [tuple(s.strip() for s in line.split(",")) for line in inf] 

def countCountries(city_list): 
    return collections.Counter(country for city,country in city_list) 

def main(): 
    cities = readFile("input.txt") 
    countries = countCountries(cities) 

    print("{0} cities found in {1} countries:".format(len(cities), len(countries))) 

    for country, num in countries.iteritems(): 
     print("{country}: {num}".format(country=country, num=num)) 

if __name__=="__main__": 
    main() 
+0

這需要python> 2.7,對吧? – arie 2011-04-09 16:43:48

+0

perfecttttt人..救ma life .. thanxxxx – Sarah 2011-04-09 16:45:24

+2

@Sarah:應該*從它*學習,而不只是*複製*它! – 2011-04-09 16:47:39

3

是的,這是一個很大的廢話你要麼不需要或不應該這樣做。下面是我在Python 2.7之前做的事情(之後,使用collections.Counter,如其他答案中所示)。請注意,這將返回包含計數的字典,而不是打印出來,您必須從外部執行此操作。我也不想爲家庭作業提供一個完整的解決方案,但它已經完成了,所以我認爲在解釋它時沒有真正的損害。

def parseFile(filename): 
    with open(filename, 'r') as fh: 
    lines = fh.readlines() 
    d={} 
    for country in [line.split(',')[1].strip() for line in lines]: 
     d[country] = d.get(country,0) + 1 
    return d 

讓我們打破這一點,我們?

with open(filename, 'r') as fh: 
    lines = fh.readlines() 

這就是您通常會打開文本文件進行閱讀的方式。如果該文件不存在或者您沒有權限或類似內容,它將引發IOError異常,因此您需要捕獲該異常。 readlines()讀取整個文件並將其分成行,每行成爲列表中的一個元素。

d={} 

這只是初始化一個空的字典

for country in [line.split(',')[1].strip() for line in lines]: 

這裏是樂趣的開始。右括號中的括號稱爲列表理解,它基本上爲您生成一個列表。它用簡單的英語簡寫爲「對於列表'行'中的每個元素'行',採用該元素/行,將其拆分爲每個逗號,將第二個元素(索引1)從分割中刪除任何空格,並將結果作爲新列表中的一個元素使用「 然後,它的左邊部分只是迭代生成的列表,給名稱'country'賦予當前元素在循環體的範圍內。

 d[country] = d.get(country,0) + 1 

好了,思考的第二個如果不是上面的線,我們會使用以下會發生什麼:

 d[country] = d[country] + 1 

它會崩潰,右(KeyError異常除外),因爲d [國家]第一次沒有價值。 所以我們使用get()方法,所有字典都有。下面是漂亮的部分 - get()需要一個可選的第二個參數,如果我們正在查找的元素不存在,那麼我們想從中獲取它。因此,不是崩潰,而是返回0,與None不同,我們可以加1,然後用新的計數更新字典。然後,我們只是返回它的很多。

希望它有幫助。

+0

很好的解釋!在[line.split(',')[1] .strip()for line in fh]中爲國家做更好的做法是:' – 2011-04-15 08:41:50

+0

你是對的,就是這樣。雖然我並不想使'更多魔術'變得更加複雜,並且爲了便於解釋,它仍然在循環之外。 – n42 2011-04-15 12:21:12

+0

我剛剛連接添加我的「+1」,從任何科目我從來沒有讀過這樣一個明確的教育答案。列表理解真的更pythonic。 – dlewin 2014-02-18 16:25:01