2014-04-28 89 views
1

我所困擾的任務是,我必須將文件的表格內容放到詞典結構的字典中。 該文件包含這樣的內容:(前六行ascii文件)Python3:文件中表格內容的詞典詞典

Name ----------- | Alt name ------- | ------ RA | ----- DEC | ----- Z^| --- CR | ---- FX | --- FX * |錯誤| --- LX | -NH-| ID- |參考號碼 - --- RXCJ0000.1 + 0816 UGC12890 0.0295 8.2744 0.0396 0.26 5.80 5.39 12.4 0.37 5.9 1,3- RXCJ0001.9 + 1204 A2692 0.4877 12.0730 0.2033 0.08 1.82 1.81 17.9 3.24 5.1 1
RXCJ0004.9 + 1142 UGC00032 1.2473 11.7006 0.0761 0.17 3.78 3.68 12.7 0.93 5.3 2,4-
RXCJ0005.3 + 1612 A2703 1.3440 16.2105 0.1164 0.24 4.96 4.94 11.8 2.88 3.7乙-2,5-
RXCJ0006.3 + 1052)1.5906 10.8677 0.1698 0.15 3.28 3.28 19.3 4.05 5.6 1

如果需要,我可以提供一個文件樣本。

下面的代碼工作正常,直到它存儲每個行字典到第二個字典。

#!/usr/bin/env python3 
from collections import * 
from re import * 
obsrun = {} 
objects = {} 
re = compile('\d+.\d\d\d\d') 

filename = 'test.asc' 

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

for l in line[2:]: 
    #split the read lines into a list 
    o_bject = l.split() 
    #print(o_bject) 
    #interate over each entry and people the line-dictionary with values of interest 
    #what's needed (in col of table): identifier, common name, rightascension, declination 
    for k in o_bject: 
    objects.__setitem__('id', o_bject[0]) 
    objects.__setitem__('common_name', o_bject[1]) 
     # sometimes the common name has blanks, multiple entries or replacements 
    if re.match(o_bject[2]): 
     objects.__setitem__('ra', float(o_bject[2])) 
     objects.__setitem__('dec', float(o_bject[3])) 
    else: 
     objects.__setitem__('ra', float(o_bject[3])) 
     objects.__setitem__('dec', float(o_bject[4])) 

    #extract the identifier (name of the object) for use as key 
    name = objects.get('id') 
    #print(name) 

    print(objects) #* 
    # as documented in http://stackoverflow.com/questions/1024847/add-to-a-dictionary-in-python 
    obsrun[name] = objects 
    #print(obsrun) 

    #getting an ordered dictionary sorted by keys 
    OrderedDict(sorted(obsrun.items(), key= lambda t: t[0])) #t[0] keys,t[1] values 

從控制檯上的輸出中可以看到的是,內部for-loop是做什麼應該做的。它由*處的打印(對象)確認。 但是,在第二個字典中存儲row-dicts的值時,它是具有相同值的人。鑰匙的製造正確。

我不明白的是,print()命令顯示「對象」的正確內容,但它們沒有正確存儲到「obsrun」中。 錯誤在於字典視圖性質還是我做錯了什麼?

我該如何改進代碼?

由於提前, 基督教

回答

1

您只創建一個字典,所以每次循環的時候,你正在修改的相同。

移動線

objects = {} 

for l in line[2:]:循環。這將爲文件的每一行創建一個單獨的字典。

此外,直接使用__setitem__是不必要的,並且使代碼難以閱讀。將行從objects.__setitem__('id', o_bject[0])更改爲objects['id'] = o_bject[0]

0

所以你說,給obsrun提供「對象」只是鏈接「對象」而不是複製內容?所以我必須保留每個內部字典,因爲它只是連接在一起。

你是對的setitem。我用它來讓我更清楚,我在那裏做了什麼。

我會嘗試移動objects = {}到內部的for循環。

感謝您的回答。如果這樣做會回來報告。

更新:這樣做了!非常感謝,我真的被困在那裏,但我學到了一些關於詞典的導入,並且在這個問題中,它們只是聯繫在一起,所以它已經存儲了內存。 歡呼聲, 基督教

1

值得指出的是,除非你試圖按名稱查找條目,否則你不需要口述字典。 (你不會在這裏解釋太多的用例。)

從代碼中跳出來的一件事就是你使用了setitem很多 - 我想也許你是來自C++或Java中,字典沒有內置語言支持。在Python中,情況並非如此 - 您可以說d [key] = value將項添加到字典中。

這裏有一些代碼來創建一個字典的列表(數組)。使Table成爲字段中的一個字典是很重要的。我會留給你弄清楚。 :)

或者,如果您的問題將要執行數據計算,則列表比dict更容易迭代。所以,如果你必須加起來或平均起來或找到最小/最大,你可能想要這個版本。 #!/ usr/bin/env python3 -tt

data = open('test.asc') 
header = data.readline().replace('-', '') 

Field_names = header.split('|') 
Table = [] 

# Read in the remaining lines, one at a time 
for line in data: 
    fields = line.split() 
    Table.append(dict(zip(Field_names, fields))) 

from pprint import pprint 

pprint(Table)