所以我有一个文本文件,例如:
RootObject: Sun
Object: Sun
Satellites: Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune,Ceres,Pluto,Haumea,Makemake,Eris
Radius: 20890260
Orbital Radius: 0
Object: Earth
Orbital Radius: 77098290
Period: 365.256363004
Radius: 6371000.0
Satellites: Moon
Object: Moon
Orbital Radius: 18128500
Radius: 1737000.10
Period: 27.321582
我想把它输入字典。这是我到目前为止,但我一直收到错误......
#d = dictionary
#new_d = new dictionary
file = open("data.txt","r")
d = {}
def data(file):
for line in file:
if line != line.strip:
continue
line = line.strip()
key = line.split(":")
val = line.split(":")
if key in d and key == "Object":
print(d)
d[key] = val
print(d)
new_d = {}
with file as x:
for d in data(x):
new_d[d["Object"]] = d
print(nd)
我应该得到这样的东西:
{' Earth': {'Satellites': ' Moon', 'Orbital Radius': ' 77098290', 'Object': ' Earth', 'Radius': ' 6371000.0', 'Period': ' 365.256363004'}, ' Moon': {'Orbital Radius': ' 18128500', 'Object': ' Moon', 'Radius': ' 1737000.10', 'Period': ' 27.321582'}, ' Sun': {'Satellites': ' Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune,Ceres,Pluto,Haumea,Makemake,Eris', 'Orbital Radius': ' 0', 'Object': ' Sun', 'Radius': ' 20890260', 'RootObject': ' Sun'}}
我收到此错误:
Traceback (most recent call last):
File "planet2.py", line 21, in <module>
for d in data(x):
TypeError: 'NoneType' object is not iterable
答案 0 :(得分:2)
这样做很好:
file = open("data.txt","r")
def data(file):
dic = {}
for line in file:
# If line not blank
if line.strip() != '':
key,value = line.split(":")
if key == 'RootObject':
dic[key] = value.strip()
elif key == 'Object':
# Get the Object value i.e Earth, Moon, Sun
obj = value.strip()
# Create entry with obj key and blank dictionary value
dic[obj]={}
else:
# Populate the blank dictionary with key, value pairs
dic[obj][key] = value.strip()
return dic
planets = data(file)
# Usage
print planets
print planets['Earth']
print planets['Earth']['Radius']
输出:
# The whole dictionary
{'Sun': {'Satellites': 'Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune,Ceres,Pluto,Haumea,Makemake,Eris', 'Orbital Radius': '0', 'Radius': '20890260'}, 'Moon': {'Orbital Radius': '18128500', 'Radius': '1737000.10', 'Period': '27.321582'}, 'Earth': {'Satellites': 'Moon', 'Orbital Radius': '77098290', 'Radius': '6371000.0', 'Period': '365.256363004'}}
# The Earth dictionary
{'Satellites': 'Moon', 'Orbital Radius': '77098290', 'Radius': '6371000.0', 'Period': '365.256363004'}
# The Earth's radius
6371000.0
答案 1 :(得分:1)
您的代码中存在一些不同的错误。导致您的异常的是您的函数data
写入全局变量并且不返回任何内容,但是您的后期代码期望它返回可迭代的内容,例如序列或生成器。
您可以通过直接在全局字典上迭代顶级代码来修复此问题,或者您可以摆脱全局并在data
中创建字典并在结尾处返回它。我建议使用后者,因为随着代码变得越来越复杂,全局变量很难处理。
这里有一个大致的概述,应该如何工作(我将离开中间部分粗略,因为我稍后会讨论):
def data(file):
objects = {}
# add stuff to objects dict
return objects
您的下一个错误是剥离线条。您的代码目前使用自己的strip
方法测试每行的不等式。这是Python 3中的错误,因为line
和line.strip
具有无法比较的类型。但即使它有效,也没有意义。我怀疑你试图消除空行,首先剥离它们然后拒绝任何空的行。以下是您可以这样做的方法:
if not line.strip():
continue
这是Python社区中某些人称之为“在你跳跃之前”(LBYL)编程风格的一个例子,因为你在它成为一个之前检查可能有问题的东西。另一种选择是“更容易请求宽恕而不是权限”(EAFP)样式,您只需在try
块中包含可能出现问题的区域并捕获生成的异常。 EAFP风格有时被认为更“Pythonic”,所以稍后我会展示这种风格。
下一个错误是逻辑错误,不会导致错误。您要分割您的行,并希望将其中的两部分放入变量key
和value
。但是,您正在对这些变量进行两次单独的分配,实际上它们最终会在每个变量中使用相同的值。这是一个你可以使用Python语法的一个很酷的功能,解压缩的地方。您可以将两个值的序列(例如列表或元组)一起分配给它们,而不是分别分配每个变量。 Python将负责将第一个值赋予第一个变量,将第二个值赋予第二个变量。这是它的样子:
key, value = line.split(":")
如果当然没有冒号,这将失败,所以如果我们使用EAFP风格的编码,这是我们放置try
块的好地方。这是一种方法:
try:
key, value = line.split(":")
except ValueError:
continue
您可以将try
块放在循环中剩余的所有内容中,然后让except
块仅包含pass
(它什么都不做,但忽略异常)。< / p>
最后,您遇到的最后一个逻辑错误与如何构建嵌套字典有关。您当前的方法是首先使用文件中的所有键和值构建单个字典,然后将它们拆分为单独的片段,每个天体对象一个。但是,如果每个对象的键相同,则不起作用。例如,由于每个对象都有一个“Orbital Radius”键,所以它们都将相互写入,将该键放入单个字典中。
@ sudo_o的答案显示了如何构建内部字典并用值填充它(它几乎与我要编写的内容相同)。我只想发表其余的解释!