我遇到的问题是,我必须将文件的表内容放在字典结构的字典中。 该文件包含以下内容:( ascii-file的前六行)
姓名----------- | 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 B 2,5
RXCJ0006.3 + 1052 a)1.5906 10.8677 0.1698 0.15 3.28 3.28 19.3 4.05 5.6 1
如有必要,我可以提供文件样本。
以下代码可以正常工作,直到将每个line-dict存储到第二个dict中。
#!/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循环完成了应该做的事情。它由*处的打印(对象)确认。 但是当在第二个字典中存储行 - 值作为值时,它是具有相同值的人。键是正确构建的。
我不明白的是,print()命令显示“对象”的正确内容,但它们没有正确存储到“obsrun”中。 错误是在dict视图中的性质还是我做错了什么?
我应该如何改进代码?
提前致谢, 基督教
答案 0 :(得分:1)
您只创建了一个字典,因此每次循环都会修改相同的字典。
移动线
objects = {}
进入for l in line[2:]:
循环。这将为文件的每一行创建一个单独的dict。
此外,直接使用__setitem__
是不必要的,并且使代码更难阅读。将行从objects.__setitem__('id', o_bject[0])
更改为objects['id'] = o_bject[0]
。
答案 1 :(得分: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)
答案 2 :(得分:0)
所以你说,给“对象”设置阻止只是链接“对象”而不是复制内容?所以我必须保留每个内部字典,因为它只是链接。
你对 setitem 是正确的。我用它来让我更清楚,我到底在做什么。
我会尝试将objects = {}移动到内部for循环中。
感谢您的回答。如果能做到这一点,我们会回来报告。
更新:那就做到了!非常感谢,我真的被困在那里,但是我学到了关于词典的重要信息,并且在这个套装中,它们只是链接在一起,所以它已经节省了内存。 干杯, 基督教