作者uranusjr (←这人是超级笨蛋)
看板Python
标题Re: [问题] if 'string' not in i:
时间Sat Aug 24 21:48:13 2013
※ 引述《sean72 (.)》之铭言:
: #Python 3.3
: a = ['a','b','c','d','x/']
: for i in a:
: if '/' not in i:
: a.remove(i)
: print(a)
: 预期输出: ['x/']
: 实际输出: ['b', 'd', 'x/']
: 为什麽 b 和 d 两个元素无法被滤掉?
: 虽然可以反向绕路 但还是非常疑惑
: tmp = []
: for i in a:
: if '/' in i:
: tmp.append(i)
: print(tmp)
: 感谢帮忙
Python 的 for-in 回圈是 iterator-based, 不是 index-based
所以你要注意 iterator-based 回圈的共同特性:
「不能在回圈内改动你正在 iterate 的东西」(包含新增/移除/更改顺序)
因为回圈所使用的 iterator 是在回圈开始前产生, 不会在回圈进行时变动
一旦你改动了该项目, 该 iterator 就无法反映项目的新状态
这时候就会开始发生一些奇怪的事情(未定义行为)
解法有很多
以你的状况而言, 最简单的改写方案是拷贝一份来 iterate
a = ['a','b','c','d','x/']
for i in
list(a):
if '/' not in i:
a.remove(i)
print(a)
因为所有的 Python 变数都是 reference
所以 list(a) 制造出来的新 list 中, 包含的项目与 a 的项目是
同样的东西
注意不是值相同, 而是真的是「同一个」
所以即使你 iterate 的是 list(a) 而非 a 本身, 仍然可以找到 a 里面的项目
--
「我最想要的同伴嘛,首先是要笑口常开,其次是我们能永远不会发生误会。
如果这些都能办到的话,嗯,如果他是世界上第一流的桥手,也还不错。」
-- 班尼多‧加罗素,前义大利蓝队成员
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.32.81.146
1F:推 timTan:可以列为程式语言最常犯的十个错之一。 08/25 00:13
2F:推 ck574b027:最後一段看起来怪怪的,就算是值相同也可以找到 a 的项 08/25 00:36
3F:→ ck574b027:目啊,跟 python 的机制没关系不是吗? 08/25 00:37
4F:推 yoshien:感谢分享 08/25 23:45
5F:推 vagic:抱歉我觉得最後一段有点怪 list(a)是copy喔 跟a不是同一个 08/27 09:52
6F:→ vagic:东西 只是值相同(就是有两条list) b=a才会指到同一个东西 08/27 09:53
7F:→ vagic:也可能是我理解力不好 这里只是为了澄清观念 感谢 08/27 09:54
8F:推 timTan:楼上要讲reference 比较好 08/27 11:58
9F:推 timTan:Reference 是强调内容物,list(a)本文有强调是新的了 08/27 12:16
10F:推 ck574b027:原文是说"包含的项目"啊,并没说a和list(a)指到同一地方 08/28 16:34
11F:推 vagic:我困惑的是下一行:"注意不是值相同, 而是真的是「同一个" 08/28 18:07
12F:→ vagic:不过感谢楼上两位 我想我概念上有比较清楚 另外抱歉表达不好 08/28 18:09