在Python中使用动态键和值更新字典

33
我有一个字典,想要动态地插入键和值,但是我没有成功。问题在于,在使用update方法时,它不会添加一对新的键值,而是会删除先前的值,所以在打印字典时只剩下最后一个值。 以下是我的代码:

我有一个字典,想要动态地插入键和值,但是我没有成功。问题在于,在使用update方法时,它不会添加一对新的键值,而是会删除先前的值,所以在打印字典时只剩下最后一个值。

i = 0
for o in iterload(f):
    i=i+1
    mydic = {i : o["name"]}
    mydic.update({i : o["name"]})
    for k, v in mydic.items():
        print(k,v) 
print(mydic)

f是我用Python代码解析的文件,结果如下:

{3: 'toto'}

这是最后一个元素。是否有办法让我的字典中包含所有元素?

非常感谢。

我还有另一个问题。

现在,我需要检查输入值是否等于字典中的键,如果是,则需要获取该键的值以继续解析文件并获取其他信息。

以下是我的代码:

f = open('myfile','r')
nb_name = input("\nChoose the number of the name :")

for o in iterload(f):
    if o["name"] == mydic[nb_name]: 
        ...

我遇到了一个KeyError错误

Traceback (most recent call last):
  File ".../test.py", line 37, in <module>
            if o["name"] == mydic[nb_name]: 
KeyError: '1'

我不明白这个问题。

3个回答

56

请移除以下这行:

    mydic = {i : o["name"]}

在循环之前添加以下内容:

mydic = {}
否则,您将在每次迭代中创建一个全新的仅包含一个元素的字典。
另外,以下内容:
mydic.update({i : o["name"]})

更简洁地写作为

mydic[i] = o["name"]

最后,注意整个循环可以重写为字典推导式:

mydic = {i+1:o["name"] for i,o in enumerate(iterload(f))}

5
你可以在调用enumerate()时传入参数 start=1,以匹配问题中的代码而不需要使用 i+1 - jfs

4
您可以使用len()来插入值:
#!/usr/bin/python

queue = {}

queue[len(queue)] = {'name_first': 'Jon', 'name_last': 'Doe'}
queue[len(queue)] = {'name_first': 'Jane', 'name_last': 'Doe'}
queue[len(queue)] = {'name_first': 'J', 'name_last': 'Doe'}

print queue

1

@NPE指出了您代码中的问题(在每次迭代中重新定义字典)。

这里有另一种生成字典的方法(Python 3代码):

from operator import itemgetter

mydict = dict(enumerate(map(itemgetter("name"), iterload(f)), start=1))

关于 KeyError: '1':在 Python 3 中,input() 返回一个字符串,但字典 mydict 需要一个整数。要将字符串转换为整数,请调用 int
nb_name = int(input("\nChoose the number of the name :"))

你为什么说这是Python 3的代码?我没有看到它在Python 2中失败的任何理由...虽然,我可能会将其编写为:dict(enumerate((x['name'] for x in iterload(f)),start=1)),或者可能移动enumeratedict((i,x['name]) for i,x in enumerate(iterload(f),start=1))。我用生成器表达式替换了map。在Python 3中,这是相同的,但这将在Python 2和Python 3中完全执行相同的操作 - 而且我认为它更容易阅读。 - mgilson
@mgilson: map 在 Python 2 中返回一个列表。要将其转换为 Python 2 代码,您可以添加 from itertools import imap as map。为了可读性,我建议使用 @NPE 答案中的字典推导式。 - jfs
我知道在py2k中map会返回一个列表。但是这段代码可能仍然有效(除非文件很大)--在这种情况下,将数据存储在字典中也可能行不通。字典推导式很好,但它要求python2.7以上的版本。我的版本使用dict试图达到一个平衡点--生成器的行为类似于你的map,但适用于python2.x,并且在我看来更易于阅读+使用dict构造函数以一种与旧版python兼容的方式创建字典。(它真的并没有比字典推导式阅读起来差多少) - mgilson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接