当前位置: 首页 > 面试题库 >

如何使用d.items()更改for循环中的所有字典键?

谢正初
2023-03-14
问题内容

我需要一些帮助来理解为什么此代码无法按预期工作。

如果要更改词典的键但保留值,则可以使用:

d[new_key] = d.pop[old_key]

我想修改所有键(并将值保留在适当的位置),但是下面的代码跳过了某些行-(“ col2”)保持不变。是因为字典是无序的,而且我不断更改其中的值吗?

在不创建新字典的情况下如何更改键并保留值?

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)

问题答案:

更改要迭代的对象绝不是一个好主意。通常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)

RuntimeError:词典在迭代过程中更改了大小

但是,在您的情况下,您为每个删除的项目添加一个项目。这使它更加混乱。要了解正在发生的事情,您需要知道字典有点像稀疏表。例如,{1: 1, 3: 3, 5: 5}像这样的字典可能看起来像这样(在Python 3.6中已更改,对于3.6及更高版本,以下内容不再正确):

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

这也是迭代的顺序。因此,在第一次迭代中,它将转到第二项(1: 1存储的项)。假设您将密钥更改为,2然后删除1该字典,则该密钥将如下所示:

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

但是我们仍处于第二行,因此,下一次迭代将转到下一个“非空”条目2: 1。汤…

使用字符串作为键会更加复杂,因为字符串哈希是随机的(基于每个会话),因此字典中的顺序是不可预测的。

在3.6中,内部布局有所更改,但此处发生了类似的事情。

假设您有以下循环:

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)

初始布局是这样的:

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

第一个循环删除,1但添加7。由于字典是在3.6中排序的,因此会在以下位置插入占位符1

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

直到您替换4为为止10

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

但是当您511字典替换时,将需要增加其大小。然后发生一些特殊的情况:占位符被删除:

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

因此,我们在上一次迭代中位于位置5,现在我们更改了第6行。但是第6行11: 5现在包含了。哎呀

永远不要更改要迭代的对象:不要在迭代过程中弄乱键(值可以)!

您可以改为保留一个“翻译表”(不知道是否违反了“不创建新字典”的要求,但需要某种存储方式以使您的代码正常工作)并在循环后进行重命名:

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)


 类似资料:
  • 问题内容: 以下代码使我有些困惑: 我不明白的是那key部分。Python如何识别它只需要从字典中读取密钥?是中的特殊字?还是仅仅是一个变量? 问题答案: 5174 只是一个变量名。 只会循环遍历字典中的键,而不是键和值。要遍历键和值,可以使用以下命令: 对于Python 3.x: 对于Python 2.x: 要测试自己,请将单词更改key为poop。 在替换为,它返回由dict支持的类似set的

  • 问题内容: 我目前有一些这样的代码: 我想发生的事情是for循环迭代并用其对应的字母替换任何大于10的值。但是,我当前的代码只是更改,而不是列表中的原始值。例如,如果设置为15,则代码始终运行并设置为,但不会更改为,而是保持为15。如何解决此问题? 问题答案: 对于循环的每次迭代,变量只会被分配一个项的值的副本,因此对所做的更改将不会反映在。 您应该更新可以通过以下函数生成的via索引项:

  • 问题内容: 这个问题已经在这里有了答案 : 如何并行地遍历两个列表? (7个答案) 5年前关闭。 我正在尝试使用for循环创建字典。这是我的代码: 输出: 为什么? 我正计划将其输出: 为什么不以这种方式输出?我们如何使其正确输出? 问题答案: 或者

  • 问题内容: 我可以在Java的for循环中更改索引吗?例如: 尽管它在for循环中执行j ++,但在for循环中,我也在执行j = j +3。对我来说有可能实现这一点吗? 问题答案: 是的,您可以在for循环内更改索引,但是这太令人困惑了。在这种情况下,最好使用while循环。

  • 问题内容: 我不知道这是否是一个愚蠢的问题,但是我需要在不使用递归的情况下动态更改for循环的数量。 例如,如果n = 3,则需要3个嵌套的for循环。 如果n = 5: 有没有什么方法可以做到这一点而无需递归?另一个问题:Java中多重调度的用途是什么?我正在尝试用一种方法编写代码,它应该在参数的不同情况下运行不同的事件。否,如果声明/三元经营者/案件。 注意:我只能使用一种方法(部分问题),并

  • 问题内容: 我创建了一个for循环,该循环循环了元素出现在容器中的次数。for循环从HTML捕获一些数据,并创建一个JSON url,然后将返回一个值。然后应将该值添加到适当位置的HTML中。 问题似乎是for循环在进行所有Ajax调用之前完成,因此仅将最后一个值添加到HTML。我以为可以确保readystate等于4,但是该解决方案不起作用。我还尝试将完整而不是成功用作Ajax事件。有什么见解吗