python序列操作_Python 序列的 +、* 操作

序列的 + 和 *

+ 和 * 都是不修改原有的操作对象, 而是构建一个全新的序列。

>>> l = [1, 2, 3]

>>> l * 5

[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]

>>> 5 * 'abcd'

'abcdabcdabcdabcdabcd'

如果一个序列当中包括一个可变的对象,这是使用 * 获取的是对象的引用。

>>> board = [['_'] * 3 for i in range(3)]

>>> board

[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]

>>> board[1][2] = 'X'

>>> board

[['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_']]

使用 * 快速创建

>>> weird_board = [['_'] * 3] * 3

>>> weird_board # 列表中的三个列表其实引用的是同一个对象

[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]

>>> weird_board[1][2] = 'O'

>>> weird_board

[['_', '_', 'O'], ['_', '_', 'O'], ['_', '_', 'O']]

等效:

>>> t = [1,2,3]

>>> l = [5,6,t]

>>> ll = l * 3

>>> ll

[5, 6, [1, 2, 3], 5, 6, [1, 2, 3], 5, 6, [1, 2, 3]]

>>> t

[1, 2, 3]

>>> t[-1] = 10

>>> ll

[5, 6, [1, 2, 10], 5, 6, [1, 2, 10], 5, 6, [1, 2, 10]]

序列的增量赋值 += 和 *=

+= 背后的特殊方法是 __iadd__ (用于“就地加法”),就像调用了 a.extend(b) 一样。

如果一个类没有实现这个方法的话, Python 会退一步调用 __add__ , 效果就变得跟 a = a + b 一样了,首先计算a +b, 得到一个新的对象, 然后赋值给a。

也就是说,变量会不会被关联到新的对象上,完全取决于第一个操作对象有没有实现 __iadd__ 方法。

*= 背后的特殊方法是 __imul__ (用于“就地乘法”),与 += 类似。

>>> l = [1, 2, 3]

>>> id(l)

4311953800

>>> l *= 2

>>> l

[1, 2, 3, 1, 2, 3]

>>> id(l)

4311953800

>>> t = (1, 2, 3)

>>> id(t)

4312681568

>>> t *= 2

>>> id(t)

4301348296

增量赋值不是原子操作

>>> t = (1,2,[30,40])

>>> t[2] = t[2] + [50,60]

Traceback (most recent call last):

File "", line 1, in t[2] = t[2] + [50,60]

TypeError: 'tuple' object does not support item assignment

>>> t

(1, 2, [30, 40])

>>> t[2] += [50,60]

Traceback (most recent call last):

File "", line 1, in t[2] += [50,60]

TypeError: 'tuple' object does not support item assignment

>>> t

(1, 2, [30, 40, 50, 60])

>>> t[2].extend([50,60])

>>> t

(1, 2, [30, 40, 50, 60, 50, 60])

1)第一种情况:运行异常,赋值失败。因为元组是不可变类型,t[2] 无法赋值。

2)第二种情况:运行异常,赋值成功。因为元组是不可变类型,所有运行异常,但 += 背后运行的是 __iadd__(t[2] 是列表,可变类型),可以完成自身“加”操作,但没法完成赋值操作,不能给 t[2] 赋值。

3)第三种情况:运行正常,赋值成功。因为 list 的 extend 方法是自身加操作,无赋值操作。没有对元组中 t[2] 进行赋值操作,所有运行无异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值