1
BrettD 2020-02-22 21:29:41 +08:00 via iPhone
是不是因为你在 for names 的循环里对 names 本体产生了修改
|
2
wwqgtxx 2020-02-22 21:38:26 +08:00 via iPhone 2
各个语言几乎都不允许在 foreach 语句中修改迭代集合本体,那样会使得迭代器失效
比如 c++中会导致悬空指针 python 中导致生成器意外退出 |
3
xupefei 2020-02-22 21:45:08 +08:00
楼上说的对。
实在不行你就倒着遍历。 |
6
crella 2020-02-22 22:26:40 +08:00
@wwqgtxx 不一定吧,ruby 的可以在循环里面删,见 https://paste.ubuntu.com/p/YHSsBXpz9c/
|
7
xiri 2020-02-22 22:28:44 +08:00
for a in names
实际执行逻辑类似 for i in range(len(names)): a=names[i] 第一遍执行,i=0,移除“王八”,names=[王九,李大,李二,赵四] 第二遍执行,i=1,a=李大,移除,names=[王九,李二,赵四] 第三遍,i=2,a=赵四,后面就不用多说了吧 |
8
xiri 2020-02-22 22:32:21 +08:00
@xiri
注意这个 range(len(names)),就算后面 len(names)发生变化,对 i 的取值也不会有影响(可以理解成在第一次执行是生成了一个列表,后面是在这个列表中迭代,不会再计算了) |
9
ybw 2020-02-22 22:37:02 +08:00 via Android
不要被楼上半桶水误导了
比如 c++支持迭代内删除 map、vector 等 记得事前做一个++操作,保存指向下一元素的指针就好了 |
10
wwqgtxx 2020-02-22 22:37:09 +08:00 via iPhone
@crella 这个吧取决于各个语言的实现,比如 java 的 iterator 要求先调用 next 才允许对旧的 iterator 执行 remove,否则会抛出 IllegalStateException
至于 ruby 的行为可能要看他的文档才能解释为何可以正常执行了 不过这种在 foreach 循环中删除元素的行为还是尽量避免的好,容易引起各种奇奇怪怪的问题 |
11
crella 2020-02-22 22:38:55 +08:00
@wwqgtxx 别说了,我已经懵 b 了,api doc 也没说明。
见 https://gitee.com/crella/rubycode/blob/master/drop_from_array.rb 我一会儿去 ruby china 问问 |
12
wwqgtxx 2020-02-22 22:41:00 +08:00 via iPhone 1
@ybw 都说了是在 foreach 中,你要是手动写 for 循环,那么一般是
if (你的判断条件) it=map.remove(it); else it++; 当然不会有这个破问题 看别人回答麻烦看仔细,别上来就说别人半桶水 |
13
crella 2020-02-22 23:19:36 +08:00
楼主现在看我的链接,应该就明白了。我也是想了一会儿。形式可能是:
i = 0 while true if (i < 数组.长度) x = 数组[i] if .... 数组.删除(x) end i += 1 else break end end 然后数组.长度是实时更新的 |
14
crella 2020-02-22 23:41:59 +08:00 via Android
@wwqgtxx 你说的是对的。ruby 遍历数组,修改 array 的同时也影响了 array.each 的抛出的变量。我发的第一段代码只不过是刚好每隔一个数就是偶数而被删除,后面我再测试一下其他的排列,得到和楼主所得的类似的结果。
不过一般都是直接对数组进行 map 操作,楼主的操作应该也是实验性质的吧。 |
15
crella 2020-02-22 23:59:14 +08:00 via Android
puts RUBY_VERSION
names = %w(王一 王二 王三) a = names.each puts a.inspect names.pop puts a.inspect 结果 2.5.1 #<Enumerator: ["王一", "王二", "王三"]:each> #<Enumerator: ["王一", "王二"]:each> 真是奇怪,我以为 enum 会保存自己的值,这里看来并不是 |
16
ik 2020-02-23 00:27:49 +08:00 via iPhone
python 的话是不是这样可解
for name in names[:]: .... |
17
ddsfeng 2020-02-23 00:28:46 +08:00
当王八成立的时候, 你把王八移除了, 而此时 王九 变成了第一个(下标 0),
而 迭代器 下次遍历时, 获取 的是下标 1 的, 因为 0 刚才才取过了.. 所以此时取到的是 李大... 依次类推... 希望你能明白.. |
18
toliho OP 哇 一天没来这么多回答,多谢各位
|
21
toliho OP |
22
toliho OP 我还发现一个问题,在 for 循环里,如果用了 if if,只会执行第二个 if ;必须用 if elif elif ……或者 if elif else
|
23
ik 2020-02-23 19:21:27 +08:00 via iPhone
|