如何用枚举列表填充字典?

How can I populate a dictionary with an enumerated list?

我有以下字典,其中键是整数,值是浮点数:

foo = {1:0.001,2:2.097,3:1.093,4:5.246}

此字典有关键字 1、2、3 和 4。

现在,我删除密钥“2”:

foo = {1:0.001,3:1.093,4:5.246}

我只剩下1、3、4键了。但我希望这些键被称为 1、2 和 3。

函数 'enumerate' 允许我获取列表 [1,2,3]:

some_list = []
for k,v in foo.items():
    some_list.append(k)
num_list = list(enumerate(some_list, start=1))

接下来,我尝试用这些新键和旧值填充字典:

new_foo = {}
for i in num_list:
    for value in foo.itervalues():
        new_foo[i[0]] = value

但是,new_foo 现在包含以下值:

{1: 5.246, 2: 5.246, 3: 5.246}

因此每个值都被 'foo' 的最后一个值替换。我认为问题出在我的 for 循环的设计上,但我不知道如何解决这个问题。有什么建议吗?

字典是这里的错误结构。使用列表;毕竟,列表会将连续的整数映射到值。

调整您的代码以从 0 而不是 1 开始,或者在索引 0 处包含一个填充值:

foo = [None, 0.001, 2.097, 1.093, 5.246]

删除 2 'key' 就这么简单:

del foo[2]

为您自动重新编号 'keys'。

这看起来很像你不应该做的事情,但我暂时假设你正在简化 MCVE 的过程,而不是实际尝试命名你的字典键 1, 2, 3, 4, 5, ...

d = {1:0.001, 2:2.097, 3:1.093, 4:5.246}
del d[2]
# d == {1:0.001, 3:1.093, 4:5.246}

new_d = {idx:val for idx,val in zip(range(1,len(d)+1),
                                    (v for _,v in sorted(d.items())))}
# new_d == {1: 0.001, 2: 1.093, 3: 5.246}

同意其他回复,列表实现了您描述的行为,因此它可能更合适,但无论如何我都会建议一个答案。

您的代码的问题在于您使用数据结构的方式。简单枚举字典中剩下的项目:

new_foo = {}
for key, (old_key, value) in enumerate( sorted( foo.items() ) ):
    key = key+1  # adjust for 1-based
    new_foo[key] = value

尝试:

foo = {1:0.001,2:2.097,3:1.093,4:5.246}
foo.pop(2)

new_foo = {i: value for i, (_, value) in enumerate(sorted(foo.items()), start=1)}

print new_foo

但是,我建议您改用普通列表,它专为快速查找无缝数字键而设计:

foo = [0.001, 2.097, 1.093, 5.245]
foo.pop(1) # list indices start at 0
print foo

正如其他人所说,最好使用列表而不是字典。但是,如果你更喜欢坚持使用字典,你可以这样做

foo = {j+1:foo[k] for j,k in enumerate(sorted(foo))}

使用类似列表理解的风格:

bar = dict( (k,v) for k,v in enumerate(foo.values(), start=1) )

但是,如评论中所述,排序将是任意的,因为 python 中的 dict 结构是无序的。要保留原始顺序,可以使用以下命令:

bar = dict( ( i,foo[k] ) for i, k in enumerate(sorted(foo), start=1) ) 

此处 sorted(foo) returns foo 的排序键列表。 i 是排序键的新枚举以及新 dict.

的新枚举

您可以将字典转换为列表,删除特定元素,然后将列表转换为字典。对不起,这不是一条线。

In [1]: foo = {1:0.001,2:2.097,3:1.093,4:5.246}
In [2]: l=foo.values()  #[0.001, 2.097, 1.093, 5.246]
In [3]: l.pop(1) #returns 2.097, not the list
In [4]: dict(enumerate(l,1))
Out[4]: {1: 0.001, 2: 1.093, 3: 5.246}

一个过滤序列的衬里,然后重新枚举并构造一个字典。

In [1]: foo = {1:0.001, 2:2.097, 3:1.093, 4:5.246}
In [2]: selected=1

In [3]: { k:v for k,v in enumerate((foo[i] for i in foo if i<>selected), 1) }
Out[3]: {1: 2.097, 2: 1.093, 3: 5.246}

我有一个更简洁的方法。

我认为它更具可读性和易于理解。您可以参考如下:

foo = {1:0.001,2:2.097,3:1.093,4:5.246}
del foo[2]
foo.update({k:foo[4] for k in foo.iterkeys()})
print foo

所以你可以得到你想要的答案。

{1: 5.246, 3: 5.246, 4: 5.246}