Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么可以';t我改变一个集合I';我在重复?_Python - Fatal编程技术网

Python 为什么可以';t我改变一个集合I';我在重复?

Python 为什么可以';t我改变一个集合I';我在重复?,python,Python,我已经看到了建议的解决方案和变通方法,但找不到一个解释,说明在迭代集合时不允许更改集合。 你能帮我理解为什么这没问题吗 In [1]: l = [1] In [2]: for i in l: l.append(2*i) if len(l)>10: break In [3]: l Out[3]: [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] 虽然这不好

我已经看到了建议的解决方案和变通方法,但找不到一个解释,说明在迭代集合时不允许更改集合。 你能帮我理解为什么这没问题吗

In [1]: l = [1]

In [2]: for i in l:
            l.append(2*i)
            if len(l)>10:
                    break

In [3]: l
Out[3]: [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
虽然这不好

In [4]: l = {1}

In [5]: for i in l:
            l.add(2*i)
            if len(l)>10:
                    break
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-5-b5bdff4a382b> in <module>()
----> 1 for i in l:
      2         l.add(2*i)
      3         if len(l)>10:
      4                 break
      5

RuntimeError: Set changed size during iteration
[4]中的
:l={1}
In[5]:对于l中的i:
l、 加(2*i)
如果len(l)>10:
打破
---------------------------------------------------------------------------
运行时错误回溯(上次最近调用)
在()
---->1对于l中的i:
2 l.添加(2*i)
3如果长度(l)>10:
4休息
5.
RuntimeError:在迭代期间设置更改的大小
迭代时更改集合有什么不好


我知道集合中的顺序没有定义,因此
next
可能会有困难。这就是原因吗?

强制集合的实现允许在迭代时进行更改将限制它具有非常差的性能。考虑一下链表和指向节点的简单迭代器。考虑扩展并需要重新分配内存的动态数组(哈希表,即
dict
set
的实现,使用这样的数组。
list
s使用这样的数组实现)等。

一个集合由一个哈希表支持(请参阅)。集合中的条目根据它们的哈希值被放入该表中,而哈希值又决定了它们的顺序

向该哈希表中添加或删除项将改变迭代顺序,有时会实质性地改变表的大小(其中所有现有项都将根据新表的大小重新划分时隙)。因为这个迭代不能在集合被改变的那一刻继续;否则,您可能会再次看到相同的值,即使顺序不同


另一方面,列表具有定义良好的顺序。插入或删除项目可以改变顺序,但必须以明确定义的方式。因此,列表迭代器可以简单地使用不断增加的索引来查找“下一个”项,直到该索引与当前列表长度匹配。

首先,您需要了解一下
集合
在封面下以同样的方式工作(在存储钥匙方面)。我认为我对这一点的解释再好不过了(这篇演讲在某种程度上回答了这个问题,并且是对
dicts
set
基础数据结构的一个惊人的参考)


基本上,对于
dicts
/
集合
来说,迭代顺序可以随着项目的添加或删除而改变。
列表的情况并非如此

您确定列表中的迭代顺序已定义,而不是简单地“脱离实现”并可能发生更改吗?@Elazar:是的,我确定。列表具有已定义的顺序。即使插入或删除了项目,从一个操作到下一个操作的顺序仍然是明确定义的。