千家信息网

Python列表和字典踩坑问题怎么解决

发表于:2025-02-23 作者:千家信息网编辑
千家信息网最后更新 2025年02月23日,这篇"Python列表和字典踩坑问题怎么解决"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看
千家信息网最后更新 2025年02月23日Python列表和字典踩坑问题怎么解决

这篇"Python列表和字典踩坑问题怎么解决"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"Python列表和字典踩坑问题怎么解决"文章吧。

一、关于列表

1.问题描述

在Python中,如果你试图在遍历一组数据的过程中,对其进行修改,这通常没什么问题。

例如:

l = [3, 4, 56, 7, 10, 9, 6, 5]for i in l:    if not i % 2 == 0:        continue    l.remove(i)print(l)

上述这段代码遍历了一个包含数字的列表,为了去除掉所有偶数,直接修改了列表l。

然而,运行后输出却是:

[3, 56, 7, 9, 5]

等一下!输出似乎不对。最终的结果仍然含有一个偶数56。为什么没有成功去除这个数呢?我们可以尝试打印出 for循环遍历的所有元素,

运行如下代码:

l = [3, 4, 56, 7, 10, 9, 6, 5]for i in l:    print(i)    if not i % 2 == 0:        continue    l.remove(i)print(l)

这段代码的输出为:

3
4
7
10
6
[3, 56, 7, 9, 5]

从输出可以看出,for循环似乎没有访问列表中的所有元素。为了解for循环在内部究竟做了什么, 我们可以使用 iter 和 next 来模拟一下。

看看下面这个例子,我使用了ipython shell 来运行代码:

In [1]: l = [3, 4, 56, 7, 10, 9, 6, 5]In [2]: # 把列表变成一个迭代器In [3]: it = iter(l)In [4]: # 使用 next() 方法来模拟 for循环In [5]: next(it)Out[5]: 3In [6]: next(it)Out[6]: 4In [7]: # 移除一个迭代器已经访问过的元素In [8]: l.remove(3)In [9]: next(it)Out[9]: 7In [10]: # 注意此处跳过了56,我们可以再移除一个元素In [11]: l.remove(4)In [12]: next(it)Out[12]: 9

上面这个实验揭示了:当你移除一个迭代器已经访问过的元素后,在下一次迭代时,会跳过右边的一个元素,直接访问下一个。

反之依然成立,即当开始迭代后,如果你在列表开头添加了一个元素,下次迭代时,可能会访问到已经迭代过的元素,

下面这段代码就出现了这种情况:

In[1]: l = [3, 4, 56, 7, 10, 9, 6, 5]In[2]: it = iter(l)In[3]: next(it)Out[3]: 3In[4]: next(it)Out[4]: 4In[5]: l.insert(0, 44)In[6]: next(it)Out[6]: 4

注意:当在列表头部添加了44后,4被访问了两次。

2.解决方案

为了解决上述问题,我们必须得确保:不能移除迭代器访问过的元素。

方案一

我们可以先对原列表进行翻转得到一个新列表,再对新列表进行迭代,并在原列表 l 中移除不符合条件的元素。

该方案代码如下:

l = [3, 4, 56, 7, 10, 9, 6, 5]# 迭代翻转后的列表for i in reversed(l):    print(i)    if not i % 2 == 0:        continue    l.remove(i)print(l)

结果如下:

5
6
9
10
7
56
4
3
[3, 7, 9, 5]

注意:迭代器现在成功访问到了列表中的所有元素,并最终输出了只含有奇数的列表。

方案二

我们还可以在开始迭代前,先复制列表 l 。但是当列表 l 中的数据过多时,这样做显然比较耗费性能。

该方案代码如下:

l = [3, 4, 56, 7, 10, 9, 6, 5]# 在这里使用 'l.copy()' 来对列表 l 进行浅拷贝for i in l.copy():      print(i)       if not i % 2 == 0:             continue      l.remove(i)print(l)

输出如下:

3
4
56
7
10
9
6
5
[3, 7, 9, 5]

该方案能保证迭代的顺序和移除元素的顺序相同。不过由于迭代和移除这两种操作针对的是两个不同的列表,因此顺序相同并不重要。

二、关于字典

1.问题描述

在对字典进行迭代时,不能修改字典。如下:

# {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}d = {k: k for k in range(10)}for k, v in d.items():      if not v % 2 == 0:            continue      d.pop(k)

这段代码会产生 RuntimeError :

Traceback (most recent call last):    File "F:/Documents/pythonprojects/01practice/app.py", line 7, in       for k, v in d.items():RuntimeError: dictionary changed size during iteration

2.解决方案

我们可以先复制字典的所有 key ,随后在迭代 key 的过程中,移除不符合条件的元素。过程如下:

# {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}d = {k: k for k in range(10)}# 这里复制了字典中的所有key值# 没有复制整个字典# 同时使用tuple()速度更快for k in tuple(d.keys()):       if not d[k] % 2 == 0:            continue      d.pop(k)    print(d)

运行代码后输出如下:

{1: 1, 3: 3, 5: 5, 7: 7, 9: 9}

我们成功移除了字典中的所有偶数键值对!

以上就是关于"Python列表和字典踩坑问题怎么解决"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。

迭代 元素 字典 代码 问题 方案 输出 内容 循环 运行 成功 偶数 过程 顺序 相同 数据 文章 条件 知识 篇文章 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 软件开发师和算法工程师哪个好 网络安全生产标准化论文 帆软怎么把excel导入数据库 2022网络安全硕士招生 chmm的服务器地址 网络安全第五空间 体会 鄞州手机软件开发平台 靖江扫码洗车软件开发 联想服务器维修调试哪家好 安徽省软件开发人员人工费 物流安全软件开发 广西本地信息服务器 u8管理服务器在哪里查找 联通网络远程服务器无响应怎么办 部队网络安全的防范知识 软件开发的简历写几页 如何进入科技互联网时代 软件开发一定要连接外网嘛 软件开发与销售合作 服务器内存被禁用怎么办 诺顿网络安全调查报告 打印服务器属性应用为灰色 我的世界服务器如何禁掉一个方块 网络正常但串口服务器测试不通 广东音视云空间安全服务器 梦 系统无法连接服务器 软件开发合同 判例 广东网络安全工程职称评价 物理删除数据库表中的应用 数据库删除一条wincc消息
0