记录一个python里面很神奇的操作,对一个包含列表的元组进行增量赋值,成功赋值但还报错

记录一个python里面很神奇的操作

今天记录一个很神奇的操作。关于序列的增量赋值。如果你很熟悉增量赋值,你也不妨看下去,我想说的是有关于增量赋值和元组之间一种神奇的操作。来自 《流畅的Python》 一书,让我们更加深入地了解里面的原理

神奇的操作

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

上面这段代码会出现什么样的情况
a. t会变成(1,2,[30,40,50,60])
b. 因为tuple不支持对它的元素赋值,所以会抛出TypeError异常
c. 以上两个都不是
d. a和b都是对的
大多数人都会认为b是正确的,本书的作者也是这么认为的,但是实际上呢?却是选 b

不要疑惑,就是这样,既报错,又成功进行了修改

首先讲一下增量赋值

我们使用增量赋值运算符 +=*= 等增量赋值运算符的时候(用 += 举例),使用的是背后的特殊方法 __iadd__,如果没有实现这个方法则会退而求其次,使用 __add__ .

两者的区别是什么?
用列表举例 a+=b,使用 __add__ 的话就像是使用了a.extend(b),如果使用 __add__ 的话,则是 a = a+b,前者是直接在原列表上进行扩展,而后者是先从原列表中取出值,在一个新的列表中进行扩展,然后再将新的列表对象返回给变量,显然后者的消耗要大些。

继续将那个神奇的操作

既然我们了解了变量赋值,那么我们就可以更深入一些了。

t[2] += [50,60] 实现原理:

  1. 将t[2]的值,存入TOS(Top Of Stack 栈的顶端)。
  2. 计算TOS +=b 。这一步可以完成,是因为TOS指向的是一个列表(可变对象)。
  3. t[2] = TOS 赋值。这一步失败,并且报错,因为t是不可变的元组

我们可以通过python tutor这个网站去找到里面运行的详细过程

原文地址:http://blog.51cto.com/13460911/2148633

时间: 2024-10-06 11:13:20

记录一个python里面很神奇的操作,对一个包含列表的元组进行增量赋值,成功赋值但还报错的相关文章

python 列表,元组,字符串 切片 超出索引值不报错

通常情况下,当我们以索引值对一个字符串,或者元组,列表取值时,如果索引超出边界,就会报错,但是如果我们使用切片呢? 字符串: 列表: 元组: 可以看到,这三种情况都没有报错,而是返回对应类型的空结果!

读书笔记--《Python基础教程第二版》--第2章列表和元组

第二章 列表和元组 2.1 序列的概览 序列:每个元素被分配一个序号  6种:列表.元组.字符串.Unicode字符串.buffer对象.xrange对象         序列可以嵌套序列          python容器的概念:序列.字典.集合 2.2 通用序列的操作 索引.分片.加.乘.属于.长度,最大值.最小值.迭代 2.2.1 索引 >>> greeting='Hello' >>> greeting[0] 'H' >>> greeting[-

Python 创建包含列表的元组

“可变”的tuple前面我们看到了tuple一旦创建就不能修改.现在,我们来看一个“可变”的tuple:>>> t = ('a', 'b', ['A', 'B'])注意到 t 有 3 个元素:'a','b'和一个list:['A', 'B'].list作为一个整体是tuple的第3个元素.list对象可以通过 t[2] 拿到:>>> L = t[2]然后,我们把list的两个元素改一改:>>> L[0] = 'X'>>> L[1] =

python3 格式化输出,字符串操作,模块,列表,元组

初识python,在网上看了老男孩的视频,建立一个博客将自己所学的python知识记录下来. input加密,用于输入密码的阶段. 1 import getpass 2 user = input("username:") 3 passwd = getpass.getpass("password:") 格式化输出 1 name = input("name:") 2 age = int (input("age:")) 3 job

python判断变量是否为int、字符串、列表、元组、字典等方法

在实际写程序中,经常要对变量类型进行判断,除了用type(变量)这种方法外,还可以用isinstance方法判断: #!/usr/bin/env python a = 1 b = [1,2,3,4] c = (1,2,3,4) d = {'a':1,'b':2,'c':3} e = "abc" if isinstance(a,int):     print "a is int" else:     print "a is not int" if 

Python(63)_写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其返回

`#-*-coding:utf-8-*- ''' 写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其返回 ''' def func(l): return l[1::2] print(func([1,2,3,4,5,7])) 原文地址:https://www.cnblogs.com/sunnybowen/p/10257583.html

python中字符串的常用操作

目的:熟练使用不同的容器或函数操作字符串,这里只介绍常用的方法. 环境:windows 7 python 3.5.3  或 ubuntu 16.04 python 3.5.2 情景:初学python接触最多的数据应该就是字符串了,处理最多的也是,熟练一些函数和方法,可以更有效率的完成想要的操作,这里只介绍处理字符串常用的一些方法. 字符串的存储: 这里的储存是更直白的说明,专业的应该是指向吧(指向确实更合理),如果不方便理解所以就暂时理解为储存吧,需要专业解释可以查看官发文档. 类型有:字符.列

python学习总结(一),第一个python程序的编写

1. python是一种解释性,编译型,互动型的语言,面向对象,动态数据类型的高级程序设计语言. 1.1 交互式:意味着可以在一个提示符直接交互执行你写的程序. 1.2 解释型:意味着开发过程中没有编译这个环节. 1.3 面向对象:意味着它支持面向对象的风格,或者代码封装在对象的编程技术. 2. python遵循 GPL(GNU General Public License)协议. 3. python的特点 相对较少的关键字,结构简单有一个明确定义的语法,代码定义清晰,容易维护,有丰富的库,跨平

python基础教程学习笔记---(2)列表和元组

1.在python中,最基本的数据结构是序列,序列中每一个元素被分配一个序号,即元素的位置,称为索引.索引从0开始,-1表示倒数第一个元素,-2表示倒数第二个元素,因此既可以是从前到后开始对元素进行访问,也可以从后往前对元素进行访问. 2.python序列中有6种内建的序列:列表.元组.字符串.Unicode字符串.buffer对象,xrange对象.其中有两种常见类型:列表和元组. 列表和元组的主要区别在于,列表可以修改,元组则不能.一般来说,在几乎所有的情况下列表都可以替代元组.一个例外情况