首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么移除元素后,Python中List的容量会减少到10,而不是8?

在Python中,List是一种动态数组,它的容量会根据需要自动调整。当我们向List中添加元素时,如果容量不足,Python会自动分配更多的内存空间来存储新的元素。这个过程中,Python会根据一定的策略来确定新分配的内存空间的大小。

在Python中,List的内存分配策略遵循了一种叫做"over-allocate"的机制。这意味着当我们向List中添加元素时,Python会预先分配比实际需要更多的内存空间。这样做的目的是为了减少频繁的内存分配操作,提高性能。

具体来说,当我们向一个空的List中添加第一个元素时,Python会分配一个固定大小的内存空间来存储这个元素。这个固定大小通常是4个字节(32位系统)或8个字节(64位系统)。当我们继续向List中添加元素时,Python会根据需要动态地分配更多的内存空间。

当List的容量不足以容纳新的元素时,Python会分配一个更大的内存空间,并将原来的元素复制到新的内存空间中。而在这个过程中,Python会根据一定的策略来确定新分配的内存空间的大小。一般来说,Python会将新分配的内存空间的大小设置为当前容量的两倍。

然而,当我们从List中移除元素时,Python并不会立即释放被移除元素所占用的内存空间。相反,Python会将这些被移除的元素标记为可回收的,并在需要时进行内存回收。这是因为频繁地释放和分配内存空间会带来一定的性能开销。

所以,当我们移除元素后,List的容量不会立即减少,而是保持不变。只有当List中的元素个数减少到一定程度时,Python才会根据一定的策略来减少List的容量。一般来说,当List中的元素个数减少到容量的四分之一左右时,Python会将List的容量减少到当前元素个数的两倍。

总结起来,移除元素后,Python中List的容量会减少到10而不是8,是因为Python采用了一种"over-allocate"的内存分配策略,为了提高性能,在移除元素后并不会立即释放被移除元素所占用的内存空间,而是在需要时进行内存回收,并在元素个数减少到容量的四分之一左右时,才会减少List的容量。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【Java提高十六】集合List接口详解

它允许任何符合规则元素插入甚至包括null。每一个ArrayList都有一个初始容量10),该容量代表了数组大小。随着容器元素不断增加,容器大小也随着增加。...每个ArrayList实例都有一个容量,该容量是指用来存储列表元素数组大小。默认初始容量10。随着ArrayList中元素增加,它容量不断自动增长。...在前面就提过ArrayList每次新增元素时都会需要进行容量检测判断,若新增元素元素个数超过ArrayList容量,就会进行扩容操作来满足新增元素需求。...在这里有一个疑问,为什么每次扩容处理会是1.5倍,不是2.5、3、4倍呢?通过google查找,发现1.5倍扩容是最好倍数。...因为Vector底层是使用数组实现,所以它操作都是对数组进行操作,只不过其是可以随着元素增加动态改变容量大小,其实现方法是是使用Arrays.copyOf方法将旧数据拷贝一个新容量数组

1.1K31

一道算术题:ArrayDeque + ArrayList = LinkedList

数组容量保证是 2 整数幂; 3、ArrayDeque 不是线程安全; 4、ArrayDeque 不支持 null 元素; 5、ArrayDeque 虽然入栈和入队有可能触发扩容,但从均摊分析上看依然是...因为 ArrayDeque 禁止存储 null 元素,所以需要逐个判断元素是否为 null 值才添加。 ‍♀️疑问 6:为什么 ArrayDeque 要求数组容量是 2 整数幂?...搬运数据过程就是把 head 头指针数组末尾元素拷贝数组头部,剩下从数组头部到尾指针元素则衔接到后面,使得所有元素规整地排列在数组头部: // 扩容操作 private void doubleCapacity...显然不是这么一回事。第一,数组容量显示是被虚拟机固化,不可能无限容量。...总结 1、ArrayDeque 是基于动态数组线性表,具备 Queue 和 Stack 行为,但不具备 List 行为; 2、ArrayDeque 数组容量是 2 整数幂,在扩容时容量翻倍,

48720

这可能是最细ArrayList详解了!

那么为何产生这种说法呢?原因是**在 jdk 1.2 ~ jdk 1.6 ,ArrayList 的确是会通过空参构造方法生成一个指定底层数据结构容量10 空数组**。...:2 // 扩容,容器容量:7 /** * 如若没有指定,默认初始容量10 ,扩容容量为原容器容量两倍...i = 0; i < 8; i++) { list2.add("填满默认容量"); } System.out.println("扩容...,容器容量:" + list2.capacity()); // 输出 // 扩容前,容器容量10 // 扩容,容器容量:20...**内存空间占用:** `ArrayList` 空间浪费主要体现在在 list 列表结尾预留一定容量空间, `LinkedList` 空间花费则体现在它每一个元素都需要消耗比 `ArrayList

86800

ArrayList详解

那么为何产生这种说法呢?原因是在 jdk 1.2 ~ jdk 1.6 ,ArrayList 的确是会通过空参构造方法生成一个指定底层数据结构容量10 空数组。...为没有存放任何元素空集合,那么在执行ensureCapacityInternal() calculateCapacity() 方法过后,minCapacity 变为 10。.../** * 如若没有指定,默认初始容量10 ,扩容容量为原容器容量两倍 */ Vector list2 = new Vector();...} System.out.println("扩容,容器容量:" + list2.capacity()); // 输出 // 扩容前,容器容量10...内存空间占用: ArrayList 空间浪费主要体现在在 list 列表结尾预留一定容量空间, LinkedList 空间花费则体现在它每一个元素都需要消耗比 ArrayList 更多空间

22230

ArrayList源码解析

(如数组)支持该接口所需工作.对于连续访问数据(如链表),应优先使用 AbstractSequentialList,不是此类....查阅资料,大概知道:transient标识之后是不被序列化 但是ArrayList实际容器就是这个数组为什么标记为不序列化??那岂不是反序列化时会丢失原来数据?...原因在于elementData是一个缓存数组,它通常会预留一些容量,等容量不足时再扩充容量,那么有些空间可能就没有实际存储元素,采用上诉方式来实现序列化时,就可以保证只序列化实际存储那些元素不是整个数组...有了上面的步骤就可以安全将集合复制elementDataindex,也就完成了集合插入. 其实我们可以看到,源码对于细节处理很细致,值得学习. 五、删除元素 1....=,不是cursor<=size,这里有点蒙 return cursor !

49120

【深入理解java集合系列】ArrayList实现原理

在添加大量元素前,应用程序也可以使用ensureCapacity操作来增加ArrayList实例容量,这可以减少递增式再分配数量。 注意,此实现不是同步。...,也导致被移除元素以后所有元素向左移动一个位置。...6) 调整数组容量: 从上面介绍向ArrayList存储元素代码,我们看到,每当向数组添加元素时,都要去检查添加元素个数是否超出当前数组长度,如果超出,数组将会进行扩容,以满足添加数据需求...,数组进行扩容时,会将老数组元素重新拷贝一份数组,每次数组容量增长大约是其原容量1.5倍。...在面对并发修改时,迭代器很快就会完全失败,不是冒着在将来某个不确定时间发生任意不确定行为风险。

36810

ArrayList源码解析,老哥,来一起复习一哈?

/** * 带一个集合参数构造方法 * * @param c 集合,代表集合元素会被放到list * @throws 如果集合为空,抛出NullPointerException */...java.util.Arrays私有内部类ArrayListtoArray()方法可能不返回Object[]。 为什么这样?...DEFAULTCAPACITY_EMPTY_ELEMENTDATA,new ArrayList(0)会将elementData 赋值为 EMPTY_ELEMENTDATA,EMPTY_ELEMENTDATA添加元素扩容容量为...1,DEFAULTCAPACITY_EMPTY_ELEMENTDATA扩容之后容量10。...面对并发修改,迭代器快速失败、清理,不是在未知时间不确定情况下冒险。请注意,快速失败行为不能被保证。通常来讲,不能同步进行并发修改几乎不可能做任何保证。

61310

《Java 算法与数据结构》第2章:数组

二维数组 二维以及多维数组,在开发场景中使用到不是不多,不过在一些算法逻辑,数学计算是可以使用。...在一些数据存放和使用场景,基本也都是使用 ArrayList 不是 LinkedList,具体性能分析参考:LinkedList插入速度比ArrayList快?你确定吗?...那么在 add 添加元素时统一完成这个事情,还是比较好处理。 之后就是随着元素添加,容量不足。当容量不足是,需要进行扩容操作。同时还得需要把旧数据迁移到新数组上。...也正因为搜索元素便捷性,才让 ArrayList 使用那么广泛。同时为了兼容可以通过元素来获取数据,不是直接通过下标,引出了 HashMap 使用哈希值计算下标的计算方式,也引出了斐波那契散列。...ArrayList 顺序添加元素,逐步测试扩容迁移元素,以及删除元素数据迁移。

41210

java核心数据结构总结

对基于链表和基于数组两种List不同实现做一些比较:   1、增加元素列表末尾:   在ArrayList源代码如下: 1 public boolean add(E e) { 2...由于ArrayList是基于数组实现数组是一块连续内存,如果在数组任意位置插入元素,必然导致该位置之后所有元素重新排序,其效率相对较低。   ...在ArrayList,对于remove()方法和add()方法一样,在任意位置移除元素,都需要数组复制。   ...,如果元素位于前半段则,从前往后找;若位置位于后半段,则从往前找,但是要移除中间元素,却几乎要遍历半个List。...如:for(int i=0;i<list.size();i++),可以将list.size()分离出来。   2、省略相同操作   3、减少方法调用,方法调用时消耗系统堆栈牺牲系统性能。

40820

Java面试题:ArrayList底层实现原理、HashMap实现原理、HashMapjdk1.7和jdk1.8有什么区别

size这个变量有两层含义:①元素个数,也就是集合长度;②下一个元素存入位置添加第一个元素时,底层创建一个新长度为10数组。...添加完毕,size++存满时,扩容1.5倍(扩容时机一:当存满时候,创建一个新数组,新数组长度 是原来1.5倍,也就是长度为15。再把所有的元素,全拷贝新数组。...1.3 ArrayList list=new ArrayList(10)list扩容几次该语句只是声明和实例了一个ArrayList,指定了容量10,未扩容。...static final int TREEIFY_THRESHOLD = 8;//当一个反树化阈值,当这个node长度减少该值就会从树转化成链表static final int UNTREEIFY_THRESHOLD...扩容逻辑:HashMap 使用是拉链法来解决散列冲突,扩容并不是必须,但是不扩容的话造成拉链长度越来越长,导致散列表时间复杂度倾向于 O(n) 不是 O(1)。

14200

【久远讲算法3】数组——最简单数据结构

(实际上在 python numpy 库是存在有数组这样一个数据结构,之后我们专门写一篇文章来分析数组和列表异同。)..., 超越指定长度时,它会进行越界报错,动态数组长度是没有准确规定,只要不超出内存,即可在数组末尾一直添加元素,这点是不是python列表很像呢?...比如我定义了一个数组,长度为 6 ,从 0 5 这6个位置,都有元素,数组已经满了,但是我们依旧想要向其中插入插入元素,这个时候我们就需要扩大数组长度了,可是数组长度在创建时就已经确定了,不是说变就可以轻易改变...删除简单地方在于,我们无需关心下标是否越界,容量是肯定不会超过申请大小。...'blue' ,打印列表可以发现,我们原列表 0 号位 'red' 和 3 号位 'blue' 都被删掉了,剩下 'red' 和 'blue' 没有被移除

79800

JDK8ArrayList工作原理剖析

JDK8源码ArrayList类结构定义如下: ?...grow(minCapacity),扩容长度是增加了原来数组数组一半大小,然后并判断了是否达到了数组扩容上限并赋值,接着把旧数组数据拷贝扩容新数组里面再次赋值给旧数组,最后把新添加元素赋值给了扩容...remove方法与add(int index, E element)正好是一个相反操作过程,移除一个元素影响一批数据位置移动,所以也是比较耗性能。 (三)查询 ? (四)修改 ?...总结: 本文介绍了JDK8ArrayList工作原理和常用方法分析,此外ArrayList非线程安全,所以需要多线程场景下,请使用jdk自带并发List结构或者Guava,Apache Common...基于数组实现List在随机访问和遍历效率比较高,但在插入指定和删除指定元素时候效率比较低,而这正好和链表相反,链表查询和随机遍历效率较低,但插入和删除指定位置元素效率比较高,这也是为什么HashMap

77650

Java ArrayList源码分析,带你拿下面试官(含扩容机制等重点问题分析)

扩容 DEFAULT_CAPACITY = 10 ) */ transient Object[] elementData; // non-private to simplify nested...add 第 2 10元素时候(以 2 举例):此时 minCapacity = size + 1 = 1 + 1 = 2 , elementData.length 已经在添加第 1 个元素等于...8, 9] 9 替换 6,r++ ,w++ 9 6 自己走一遍上面的逻辑,就能深刻感受得到 这步作用:把需要移除数据都替换掉,不需要移除数据前移。...当突然 ArrayList remove 方法被调用(不是 Itr remove),导致被删除元素后面的所有元素都会往前移动一位,且 modCount 这个修改次数增加,继续循环,去执行 next...} } } //运行结果 I love you ❤ 两者均可以解决并发修改异常问题,但是通过运行结果也可以看出,方法一添加,在本次遍历不会输出添加结果,方法二却可以。

1.5K22

Java 集合框架(3)---- List 相关类解析(下)

/** * 记录数组列表中元素个数 */ private int size; 看到这里可能有些小伙伴们问了:不是说 ArrayList 类默认构造方法会构造出一个容量为...10 数组吗,为什么在 ArrayList 类默认构造函数只看到了一句 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; 代码,并且在后面的代码也显示出这个...好了,这样的话我们就把 ArrayList 添加元素整个流程过了一遍,主要流程也不复杂: 先判断元素数组是否需要扩容 ⇒ 确定扩容容量(第一次将容量调整为默认容量10),之后 以1.5 倍数进行扩容...)⇒ 判断扩容容量是否溢出 ⇒ 进行数组扩容并复制原数组元素新数组。...1 size 变成 oldSize + 1,之后线程 1 将主内存 size 值更新为 oldSize + 1(其实线程 2 之前已经将主内存 size 值加一了),此时出现了明明添加了两个元素

65440

大厂必问Java集合面试题

ArrayList扩容本质就是计算出新扩容数组size实例化,并将原有数组内容复制新数组中去。默认情况下,新容量会是原容量1.5倍。...实现,优化了高位运算算法,通过hashCode()高16位异或低16位实现:这么做可以在数组比较小时候,也能保证考虑高低位都参与Hash计算,可以减少冲突,同时不会有太大开销。...1.8扩容机制:当元素个数大于threshold时,进行扩容,使用2倍容量数组代替原有数组。采用尾插入方式将原数组元素拷贝新数组。...非阻塞队列几种主要方法: add(E e) : 将元素e插入队列末尾,如果插入成功,则返回true;如果插入失败(即队列已满),则会抛出异常; remove() :移除队首元素,若移除成功,则返回...所谓通知模式,就是当生产者往满队列里添加元素时会阻塞生产者,当消费者消费了一个队列元素,会通知生产者当前队列可用。

1.3K31

彻底搞懂ArrayList

=Object[].class,那么重新拷贝一份数据数组,并且elementData会指向新数组。...extends E> c构造ArrayList,为什么先调用c.toArray(),然后再判断size大小呢,不是先调用c.size判断大小,再调用c.toArray()?...答案:不通过迭代器删除元素时,由于数据进行前移,可能(不是一定,要考虑元素位置)造成数组越界和数据遗漏(i+1元素前移到i位置,那么原来i+1元素就会被遗漏掉),通过迭代器remove删除元素...至于为什么移除元素必须调用next方法是因为迭代器remove元素必须要遍历过,如果没有遍历过那么lastRet=-1,迭代器抛出异常,而且删除lastRet重新等于-1,所以每次删除都需要调用next...答案:影响,在SubList源码我们可以发现,其内部操作函数实际上都是对ArrayListelementData操作。

42331

最全集合干货送给大家

,数组也可以用 for-each 循环遍历,如下: Object[] list = new Object[10]; for (Object obj: list){} 那么,为什么实现了此接口对象可以进行...上述循环遍历经过反编译如下: // 数组 Object[] list = new Object[10]; Object[] var14 = list; int var15 = list.length...为什么说是安全遍历元素移除元素,添加元素?...尝试查询不合法元素抛出异常,或者可能仅仅返回 false。一些将展示前者行为一些将展示后者行为。大致上来说,尝试对不合格元素进行操作,其完成操作不会导致将不合格元素插入集合。...此值太高会减少空间开销但是增加查找时间成本,这会反应在 get、put 操作。 初始容量控制了浪费空间与 rehash 操作需求之间权衡,这是非常耗时

62310
领券