将数据输入字典

时间:2012-11-22 20:03:47

标签: python python-3.x dictionary input

所以我有一个文本文件,例如:

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

2 个答案:

答案 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中的错误,因为lineline.strip具有无法比较的类型。但即使它有效,也没有意义。我怀疑你试图消除空行,首先剥离它们然后拒绝任何空的行。以下是您可以这样做的方法:

if not line.strip():
    continue

这是Python社区中某些人称之为“在你跳跃之前”(LBYL)编程风格的一个例子,因为你在它成为一个之前检查可能有问题的东西。另一种选择是“更容易请求宽恕而不是权限”(EAFP)样式,您只需在try块中包含可能出现问题的区域并捕获生成的异常。 EAFP风格有时被认为更“Pythonic”,所以稍后我会展示这种风格。

下一个错误是逻辑错误,不会导致错误。您要分割您的行,并希望将其中的两部分放入变量keyvalue。但是,您正在对这些变量进行两次单独的分配,实际上它们最终会在每个变量中使用相同的值。这是一个你可以使用Python语法的一个很酷的功能,解压缩的地方。您可以将两个值的序列(例如列表或元组)一起分配给它们,而不是分别分配每个变量。 Python将负责将第一个值赋予第一个变量,将第二个值赋予第二个变量。这是它的样子:

key, value = line.split(":")

如果当然没有冒号,这将失败,所以如果我们使用EAFP风格的编码,这是我们放置try块的好地方。这是一种方法:

try:
    key, value = line.split(":")
except ValueError:
    continue

您可以将try块放在循环中剩余的所有内容中,然后让except块仅包含pass(它什么都不做,但忽略异常)。< / p>

最后,您遇到的最后一个逻辑错误与如何构建嵌套字典有关。您当前的方法是首先使用文件中的所有键和值构建单个字典,然后将它们拆分为单独的片段,每个天体对象一个。但是,如果每个对象的键相同,则不起作用。例如,由于每个对象都有一个“Orbital Radius”键,所以它们都将相互写入,将该键放入单个字典中。

@ sudo_o的答案显示了如何构建内部字典并用值填充它(它几乎与我要编写的内容相同)。我只想发表其余的解释!