本文介绍了如何用d.items()更改for循环中的所有字典键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



如果您想更改字典的关键字但保留该值,那么他/她可能会用:

  d [new_key] = d.pop [old_key] 

我想修改所有的键(并保留值),但下面的代码跳过某些行 - (col2)保持不变。是因为字典是无序的,我不断改变它的价值?

我将如何去改变键和保留值,而不创建一个新的字典? p>

 导入时间
导入pprint

name_dict = {col1:973,col2 :1452 29th Street,
col3:这是一个值,col4:这是另一个值,
col5:NULL,col6: Scottsdale,
col7:N / A,col8:41.5946922,
col9:Building,col10:Commercial}
$ ():
print(这是关键:'%s',这是'%s'' ,v))
new_key = input(请输入一个新的键:)
name_dict [new_key] = name_dict.pop(k)
time.sleep(4)

pprint.pprint(name_dict)


解决方案

从来没有一个好主意来改变你正在迭代的对象过度。通常 dict 甚至会在您尝试时引发异常:

  name_dict = {1:1,2:2,3:3,4:4,5:5,6:6} 

for k,v in name_dict.items():
name_dict。 pop(k)



然而,在您的情况下,您为每个移除的项目添加一个项目。这使得它更加卷入。要了解发生了什么,你需要知道字典有点像一个稀疏的表。例如像 {1:1,3:3,5:5} 这样的字典可能看起来像这样(这在Python 3.6中改变了,对于3.6和更新的版本, )

 哈希键值
- - -
1 1 1
- - -
3 3 3
- - -
5 5 5
- - -
- - -
- - -

这也是迭代的顺序。所以在第一次迭代中,它将转到第二项(存储 1:1 )。让我们假设你将键改为 2 ,并删除键 1 字典看起来像这样:

 哈希键值
- - -
- - -
2 2 1
3 3 3
- - -
5 5 5
- - -
- - -
- - -

但是我们仍然在第二行,所以下一个迭代将进入下一个非空条目,它是 2 :1 。 Oups ...
$ b

字符串作为键更复杂,因为字符串散列是随机的(按每个会话),所以字典内部的顺序是不可预知的。 p>

在3.6版本中,内部布局有所改变,但是在这里发生了类似的情况。



假设你有这个循环: / p>

  name_dict = {1:1,2:2,3:3,4:4,5:5,6:6} 

for k,v in name_dict.items():
#print(k,k + 6,name_dict .__ sizeof __())
name_dict [k + 6] = name_dict .pop(k)
print(name_dict)

初始布局如下所示:

 键值
1 1
2 2
3 3
4 4
5 5
6 1

第一个循环移除 1 ,但添加 7 。因为字典是在3.6中定义的,所以插入一个占位符,其中 1 已经被占据:

 键值
- -
2 2
3 3
4 4
5 5
6 1
7 2

直到您用<$ c $替换 4 c> 10 。

 键值
- -
- -
- -
- -
5 5
6 1
7 2
8 3
9 4
10 5

但是当用 5 > 11 字典将需要增加它的大小。然后会发生一些特殊情况:占位符被删除:

pre $ key $ value $ b $ 6
7 1
8 2
9 3
10 4
11 5

所以,我们在最后一次迭代中的位置5,现在我们改变了第6行。但是第6行现在包含 11:5 。 Oups ...

永远不要改变迭代的对象:不要在迭代过程中乱用键(值可以)!$ / b
$ b

你可以保留一个翻译表(不知道是否违反了你的没有创建一个新的字典的要求,但你需要一些存储,使您的代码正常工作)和在循环之后重命名:

  translate = {} 
for k,v in name_dict.items():
print(这是关键:'%s',这是'%s'\\\
'%(k,v))
的值new_key = input(请输入一个新的密钥:)
translate [k] = new_key
time.sleep(4)

for translate.items()中的旧的,新的:
name_dict [new] = name_dict.pop(旧)


I would like some help with understanding why this code is not working as expected.

If one wants to change the key of a dictionary but keep the value, he/she might use:

d[new_key] = d.pop[old_key]

I want to modify all the keys (and keep the values in place) but the code below skips certain lines - ("col2") remains untouched. Is it because dictionaries are unordered and I keep changing the values in it?

How would I go about changing the keys and keep the values without creating a new dictionary?

import time
import pprint

name_dict = {"col1": 973, "col2": "1452 29th Street",
             "col3": "Here is a value", "col4" : "Here is another value",
             "col5" : "NULL", "col6": "Scottsdale",
             "col7": "N/A", "col8" : "41.5946922",
             "col9": "Building", "col10" : "Commercial"}


for k, v in name_dict.items():
    print("This is the key: '%s' and this is the value '%s'\n" % (k, v) )
    new_key = input("Please enter a new key: ")
    name_dict[new_key] = name_dict.pop(k)
    time.sleep(4)

pprint.pprint(name_dict)
解决方案

It's never a good idea to change the object you're iterating over. Normally dict even throws an exception when you attempt it:

name_dict = {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6}

for k, v in name_dict.items():
    name_dict.pop(k)

However in your case you add one item for every removed item. That makes it more convolved. To understand what's happening you need to know that a dictionary is somewhat like a sparse table. For example a dictionary like {1: 1, 3: 3, 5: 5} could look like this (this changed in Python 3.6, for 3.6 and newer the following isn't correct anymore):

hash    key    value
   -      -        - 
   1      1        1
   -      -        - 
   3      3        3
   -      -        - 
   5      5        5
   -      -        - 
   -      -        - 
   -      -        - 

That's also the order in which it is iterated. So in the first iteration it will go to the second item (where the 1: 1 is stored). Let's assume you change the key to 2 and remove the key 1 the dict would look like this:

hash    key    value
   -      -        - 
   -      -        - 
   2      2        1
   3      3        3
   -      -        - 
   5      5        5
   -      -        - 
   -      -        - 
   -      -        - 

But we're still at the second line, so the next iteration it will go to the next "not-empty" entry which is 2: 1. Oups ...

It's even more complicated with strings as keys because string hashes are randomized (on a per session basis) so the order inside the dictionary is unpredictable.

In 3.6 the internal layout was changed a bit but something similar happens here.

Assuming you have this loop:

name_dict = {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6}

for k, v in name_dict.items():
    # print(k, k+6, name_dict.__sizeof__())
    name_dict[k+6] = name_dict.pop(k)
    # print(name_dict)

The initial layout is like this:

key   value
  1       1
  2       2
  3       3
  4       4
  5       5
  6       1

The first loop removes 1 but adds 7. Because dictionaries are ordered in 3.6 this inserts a placeholder where 1 had been:

key   value
  -       -
  2       2
  3       3
  4       4
  5       5
  6       1
  7       2

This goes on until you replace 4 with 10.

key   value
  -       -
  -       -
  -       -
  -       -
  5       5
  6       1
  7       2
  8       3
  9       4
 10       5

But when you replace 5 with 11 the dictionary will need to increase it's size. Then something special happens: The placeholders are removed:

key   value
  6       6
  7       1
  8       2
  9       3
 10       4
 11       5

So, we were at position 5 in the last iteration and now we change line 6. But line 6 contains 11: 5 right now. Oups...

Never change the object you're iterating over: Don't mess with the keys during iteration (values are okay)!

You could instead keep a "translation table" (don't know if that violates your "without creating a new dict" requirement but you need some kind of storage to make your code work correctly) and do the renaming after the loop:

translate = {}
for k, v in name_dict.items():
    print("This is the key: '%s' and this is the value '%s'\n" % (k, v) )
    new_key = input("Please enter a new key: ")
    translate[k] = new_key
    time.sleep(4)

for old, new in translate.items():
    name_dict[new] = name_dict.pop(old)

这篇关于如何用d.items()更改for循环中的所有字典键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 22:36