Python中list列表的赋值方法及遇到问题处理

目录
  • 1.列表list赋值方法
  • 2.浅拷贝(shallowcopy)
  • 3.深拷贝
  • 4.关于拷贝操作的提醒

问题起源:

本文的原因是因为在使用list的直接赋值b=a时,得到的结果与预期不同,后来才发现直接使用等于号=对列表进行赋值会产生一系列的问题,于是将赋值、浅拷贝、深拷贝三者之间的区别进行记录。

1.列表list赋值方法

在python中,对象的赋值就是简单的对象引用,这点和C++是不同的,

如下例子所示:

a = ['a', 'b', 'c']
b = a   # 采用简单的=赋值
print(a==b)

# 下面是输出结果:
True

上面这种情况下,b和a是一样的,他们指向同一片内存,b不过是a的别名,是引用。我们可以使用a与b是否相同来判断,返回True,表明他们地址相同,内容相同。
赋值操作(包括对象作为参数、返回值)不会开辟新的内存空间,它只是复制了新对象的引用。也就是说,除了b这个名字以外,没有其它的内存开销。
修改了a,就影响了b;同理,修改了b就影响了a。下面的例子尝试对b进行修改,在后面加入新的元素’d’,通过观察输出结果发现:在修改列表b的同时,列表a也会被修改,因为两者用的是同一个内存空间。

a = ['a', 'b', 'c']
b = a
b.append('d')
print('a = {}'.format(a))
print('b = {}'.format(b))

# 下面是输出结果:
a = ['a', 'b', 'c', 'd']
b = ['a', 'b', 'c', 'd']

2.浅拷贝(shallow copy)

浅拷贝会创建新对象,其内容是原对象的引用。
浅拷贝有三种形式:切片操作,工厂函数,copy模块中的copy函数。

比如对上述a:

  • 1、切片操作:b = a[:] 或者 b = [each for each in a]
  • 2、工厂函数:b = list(a)
  • 3、copy函数:b = copy.copy(a) #使用时要import copy模块

浅拷贝产生的b不再是a了,使用is可以发现他们不是同一个对象,使用id查看,发现它们也不指向同一片内存。但是当我们使用 id(x) for x in a 和 id(x) for x in b 时,可以看到二者包含的元素的地址是相同的。
在这种情况下,a和b是不同的对象,修改b理论上不会影响a。比如b.append([4,5])。

代码效果如下:

a = ['a', 'b', 'c', ['yellow', 'red']]
b = a[:]  # 采用了切片操作对列表b进行赋值
b.append('green') # 对列表b执行添加元素操作
print('a = {}'.format(a))
print('b = {}'.format(b))

# 下面是输出结果:
a = ['a', 'b', 'c', ['yellow', 'red']]  # a中的元素不发生变化
b = ['a', 'b', 'c', ['yellow', 'red'], 'green']  # b中增加了一个元素'green'

但是要注意:浅拷贝之所以称为浅拷贝,是它仅仅只拷贝了一层,在a中有一个嵌套的list,如果我们修改了它,情况就不一样了。
    a[3].append(“blue”)。查看b,你将发现b也发生了变化。这是因为,你修改了嵌套的list。修改外层元素,会修改它的引用,让它们指向别的位置,修改嵌套列表中的元素,列表的地址并为发生变化,指向的都是同一个位置。

代码如下:

a = ['a', 'b', 'c', ['yellow', 'red']]
b = a[:]  # 采用了切片操作对列表b进行赋值
a[3].append('blue')  # 在a列表中的第3个元素中增加元素'blue',由于a[3]本身也是一个列表,从而是在列表后增加了元素'blue',从输出结果中可以看出来。
print('a = {}'.format(a))
print('b = {}'.format(b))

# 下面是输出结果:
a = ['a', 'b', 'c', ['yellow', 'red', 'blue']]
b = ['a', 'b', 'c', ['yellow', 'red', 'blue']]

3.深拷贝

深拷贝只有一种形式,copy模块中的deepcopy函数。
和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。因而,它的时间和空间开销要高。
同样对la,若使用b = copy.deepcopy(a),再修改b将不会影响到a了。即使嵌套的列表具有更深的层次,也不会产生任何影响,因为深拷贝出来的对象根本就是一个全新的对象,不再与原来的对象有任何关联。

实例代码如下:

import copy
a = ['a', 'b', 'c', ['yellow', 'red']]
b = copy.deepcopy(a)   # 采用深拷贝对a进行深拷贝操作
b.append('xyz')
print('a = {}'.format(a))
print('b = {}'.format(b))

# 下面是输出结果:
a = ['a', 'b', 'c', ['yellow', 'red']]   # 使用深拷贝,对b的修改不会影响到a
b = ['a', 'b', 'c', ['yellow', 'red'], 'xyz']

或者用下面的代码:

import copy
a = ['a', 'b', 'c', ['yellow', 'red']]
b = copy.deepcopy(a)   # 采用深拷贝对a进行深拷贝操作
a[3].append('crazy')
print('a = {}'.format(a))
print('b = {}'.format(b))

# 下面是输出结果:
a = ['a', 'b', 'c', ['yellow', 'red', 'crazy']]  
b = ['a', 'b', 'c', ['yellow', 'red']]   # 对a的修改不会影响到b

或者用下面的代码:

import copy
a = ['a', 'b', 'c', ['yellow', 'red']]
b = copy.deepcopy(a)   # 采用深拷贝对a进行深拷贝操作
a[3].append('crazy')
b.append('dddd')
print('a = {}'.format(a))
print('b = {}'.format(b))

# 下面是输出结果:
a = ['a', 'b', 'c', ['yellow', 'red', 'crazy']]
b = ['a', 'b', 'c', ['yellow', 'red'], 'dddd']

4.关于拷贝操作的提醒

  • 1、对于非容器类型,如数字,字符,以及其它“原子”类型,没有拷贝一说。产生的都是原对象的引用。
  • 2、如果元组变量值包含原子类型对象,即使采用了深拷贝,也只能得到浅拷贝。

到此这篇关于Python中list列表的赋值方法及遇到问题处理的文章就介绍到这了,更多相关list列表赋值方法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python list sort方法的具体使用

    目录 描述 语法 使用示例 1. 所有参数都省略 2. 指定key参数 3. 指定reverse参数 注意事项 1. sort函数会改变原列表顺序 2. 列表元素类型不一致 3. Python早些版本 描述 list.sort()方法是Python的列表方法,用于对原列表进行排序.list.sort()方法没有任何返回值. 语法 list.sort(key=function, reverse=boolean) 名称 说明 备注 list 列表名称 key=function 列表元素权值参数 可省

  • Python中移除List重复项的五种方法

    本文列些处几种去除在Python 列表中(list)可能存在的重复项,这在很多应用程序中都会遇到的需求,作为程序员最好了解其中的几种方法 以备在用到时能够写出有效的程序. 方法1:朴素方法 这种方式是在遍历整个list的基础上,将第一个出现的元素添加在新的列表中. 示例代码: # Python 3 code to demonstrate # removing duplicated from list # using naive methods # initializing list test_l

  • python list.sort()根据多个关键字排序的方法实现

    目录 前言: 另一用法 sort 与 sorted 区别: 前言: 加入我需要对如下几个文件按照从下到大排序,可是他的关键字有多个应该怎么办了? 例如我希望005开头在006和007的前面,然后005内部我希望12排在15前面 005x12.jpg 006x01.jpg 007x03.jpg 005x15.jpg 007x10.jpg 006x04.jpg 解决方法: 利用list.sort()中的多个关键字排序功能,先按照key1排序,再按照key2排序 list.sort(key=lambd

  • Python3 列表list合并的4种方法

    下面是列表合并的4种方法,其中的代码都在Python3下测试通过,在Python2下运行应该也没问题,时间关系就没测试,遇到问题可以联系小编 方法1: 直接使用"+"号合并列表 aList = [1,2,3] bList = ['www', 'jb51.net'] cList = aList + bList dList = bList + aList print(cList) print(dList) 输出为: [1, 2, 3, 'www', 'jb51.net'] ['www',

  • Python list列表删除元素的4种方法

    目录 del:根据索引值删除元素 pop():根据索引值删除元素 remove():根据元素值进行删除 clear():删除列表所有元素 在 Python 列表中删除元素主要分为以下 3 种场景: 根据目标元素所在位置的索引进行删除,可以使用 del 关键字或者 pop() 方法: 根据元素本身的值进行删除,可使用列表(list类型)提供的 remove() 方法: 将列表中所有元素全部删除,可使用列表(list类型)提供的 clear() 方法. del:根据索引值删除元素 del 是 Pyt

  • Python中list列表的赋值方法及遇到问题处理

    目录 1.列表list赋值方法 2.浅拷贝(shallowcopy) 3.深拷贝 4.关于拷贝操作的提醒 问题起源: 本文的原因是因为在使用list的直接赋值b=a时,得到的结果与预期不同,后来才发现直接使用等于号=对列表进行赋值会产生一系列的问题,于是将赋值.浅拷贝.深拷贝三者之间的区别进行记录. 1.列表list赋值方法 在python中,对象的赋值就是简单的对象引用,这点和C++是不同的, 如下例子所示: a = ['a', 'b', 'c'] b = a   # 采用简单的=赋值 pri

  • Python中的列表条件求和方法

    目录 列表条件求和方法 利用列表求和函数(可接收无数个参数求和) 列表条件求和方法 list_data=[ [1.0, '配件', '522422', '铝扣板用纽扣', '金色', '', 72.0, 'PC', ''], [2.0, '配件', '500031', '十字槽沉头自钻自攻螺钉4.2*45', '原色', '', 72.0, 'PC', ''], [1.0, '配件', '522422', '铝扣板用纽扣', '原色', '', 24.0, 'PC', ''], [2.0, '配

  • 在Python中处理列表之reverse()方法的使用教程

    reverse()方法代替逆转列表对象. 语法 以下是reverse()方法的语法: list.reverse() 参数 NA 返回值 此方法不返回任何值,但反转列表中的给定对象. 例子 下面的例子显示了reverse()方法的使用. #!/usr/bin/python aList = [136, 'xyz', 'zara', 'abc', 'xyz','hema']; aList.reverse(); print "List : ", aList; 当我们运行上面的程序,它会产生以下

  • python中list列表复制的几种方法(赋值、切片、copy(),deepcopy())

    目录 1.浅拷贝和深拷贝 2.直接赋值 3.for循环 4.切片 5.copy()方法 (1)list.copy()方法 (2)copy.copy()方法 6.deepcopy()方法 1.浅拷贝和深拷贝 浅拷贝复制指向某个对象的地址(指针),而不复制对象本身,新对象和原对象共享同一内存. 深拷贝会额外创建一个新的对象,新对象跟原对象并不共享内存,修改新对象不会影响到原对象. 赋值其实就是引用了原对象.两者指向同一内存,两个对象是联动的,无论哪个对象发生改变都会影响到另一个. 2.直接赋值 使用

  • Python中遍历列表的方法总结

    Python中遍历列表有以下几种方法: 一.for循环遍历 lists = ["m1", 1900, "m2", 2000] for item in lists: print(item) lists = ["m1", 1900, "m2", 2000] for item in lists: item = 0; print(lists) 运行结果: ['m1', 1900, 'm2', 2000] 二.while循环遍历: li

  • Python 中判断列表是否为空的方法

    在判断列表是否为空时,你更喜欢哪种方式?决定因素是什么? 在 Python 中有很多检查列表是否是空的方式,在讨论解决方案前,先说一下不同方法涉及到的不同因素. 我们可以把判断表达式可以分为两个阵营: 对空列表的显式比较 对空列表的隐式求值 这意味着什么? 显式比较 我们从显式比较开始说起,无论我们使用列表符号 [] 还是声明空列表的函数 list() ,遵循的策略是查看待检查列表是否与空列表完全相等. # 都是用来创建空列表 a = [] b = list() print(a == b) #

  • python中对二维列表中一维列表的调用方法

    python调用二维列表中的一维列表的方法: 访问二维列表中的一维列表可以用下标法"列表名(数字)"的方式获取到一维列表所有元素 x = [[23, 25, 15, 69, 48], [53, 98, 87, 478, 365], [231, 55, 653, 589, 545, 123]] print(x[0]) 执行结果: 内容扩展: 二维列表转一维列表 from compiler.ast import flatten a=[[1,2],[5,6]] print(flatten(a

  • python中list列表删除元素的四种方法实例

    目录 在python列表中删除元素主要分为以下3种场景: del:根据索引值删除元素 pop():根据索引值删除元素 remove():根据元素值进行删除 clear():删除所有元素 补充: 删除元素的变相方法 总结 在python列表中删除元素主要分为以下3种场景: 根据目标元素所在的索引位置进行删除,可以使用del关键字或pop()方法: 根据元素本身的值进行删除,可使用列表(list类型)提供的remove()方法: 将列表中所有元素全部删除,可使用列表(list类型)提供的clear(

  • python中常见错误及解决方法

    python常见的错误有 1.NameError变量名错误 2.IndentationError代码缩进错误 3.AttributeError对象属性错误 详细讲解 1.NameError变量名错误 报错: >>> print a<br>Traceback (most recent call last):<br>File "<stdin>", line 1, in <module><br>NameError:

  • python 安全地删除列表元素的方法

    目录 方法1:创建新列表,过滤元素 1a)列表推导,创建新列表 1b)列表推导,对a[:]赋值 1c)使用itertools.filterfalse() 方法2:列表副本上迭代 常见陷阱 前言: 看似简单的任务,往往隐藏陷阱! 一个常见的任务是在一个列表上迭代,并根据条件删除一些元素.本文将展示如何完成该任务的不同方法,同时展示一些需要避免的陷阱. 假设我们需要修改列表a,并且必须删除所有不是偶数的项. 首先实现辅助函数even(x)来确定一个数字x是否是偶数: a = [1, 2, 2, 3,

随机推荐