记忆模糊知识点5-11
列表 list:
>>> classmates = ['Michael', 'Bob', 'Tracy'] >>> classmates ['Michael', 'Bob', 'Tracy']
list是一个可变的有序表,所以,可以往list中追加元素到末尾:
>>> classmates.('Adam') >>> classmates ['Michael', 'Bob', 'Tracy', 'Adam']
也可以把元素插入到指定的位置,比如索引号为1
的位置:
>>> classmates.(1, 'Jack') >>> classmates ['Michael', 'Jack', 'Bob', 'Tracy', 'Adam']
要删除list末尾的元素,用pop()
方法:
>>> classmates.pop() 'Adam' >>> classmates ['Michael', 'Jack', 'Bob', 'Tracy']
要删除指定位置的元素,用pop(i)
方法,其中i
是索引位置:
>>> classmates.pop(1) 'Jack' >>> classmates ['Michael', 'Bob', 'Tracy']
list元素也可以是另一个list,比如:
>>> s = ['python', 'java', ['asp', 'php'], 'scheme'] >>> len(s) 4
要注意s
只有4个元素,其中s[2]
又是一个list,如果拆开写就更容易理解了:
>>> p = ['asp', 'php'] >>> s = ['python', 'java', p, 'scheme']
要拿到'php'
可以写p[1]
或者s[2][1]
,因此s
可以看成是一个二维数组,类似的还有三维、四维……数组,不过很少用到。
如果一个list中一个元素也没有,就是一个空的list,它的长度为0:
>>> L = [] >>> len(L) 0
列表 :tuple(元组)
另一种有序列表叫元组:tuple。tuple和list非常类似,但是tuple一旦初始化就不能修改,比如同样是列出同学的名字:
>>> classmates = ('Michael', 'Bob', 'Tracy')
现在,classmates这个tuple不能变了,它也没有append(),insert(),pop()这样的方法。其他获取元素的方法和list是一样的,你可以正常地使用classmates[0]
,classmates[-1]
,但不能赋值成另外的元素。
不可变的tuple有什么意义?因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。
tuple的陷阱:如果定义只有一个元素的元组:
>>> t = (1)
>>> t
1
定义的不是tuple,是1
这个数!这是因为括号()
既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python规定,这种情况下,按小括号进行计算,计算结果自然是1
。
所以,只有1个元素的tuple定义时必须加一个逗号,
,来消除歧义:
>>> t = (1,) >>> t (1,)
最后来看一个“可变的”tuple:
>>> t = ('a', 'b', ['A', 'B']) >>> t[2][0] = 'X' >>> t[2][1] = 'Y' >>> t ('a', 'b', ['X', 'Y'])
表面上看,tuple的元素确实变了,但其实变的不是tuple的元素,而是list的元素。tuple一开始指向的list并没有改成别的list,所以,tuple所谓的“不变”是说,tuple的每个元素,指向永远不变。即指向'a'
,就不能改成指向'b'
,指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!
循环:if
if
语句执行有个特点,它是从上往下判断,如果在某个判断上是True
,把该判断对应的语句执行后,就忽略掉剩下的elif
和else
,所以,请测试并解释为什么下面的程序打印的是teenager
:
age = 20 if age >= 6:print 'teenager' elif age >= 18:print 'adult' else:print 'kid'
if
判断条件还可以简写,比如写:
if x:print 'True'
只要x
是非零数值、非空字符串、非空list等,就判断为True
,否则为False
while 循环:
循环是让计算机做重复任务的有效的方法,有些时候,如果代码写得有问题,会让程序陷入“死循环”,也就是永远循环下去。这时可以用Ctrl+C
退出程序,或者强制结束Python进程。
字典:dict
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} >>> d['Michael'] 95
把数据放入dict的方法,除了初始化时指定外,还可以通过key放入:
>>> d['Adam'] = 67 >>> d['Adam'] 67
由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉:
>>> d['Jack'] = 90 >>> d['Jack'] 90 >>> d['Jack'] = 88 >>> d['Jack'] 88
如果key不存在,dict就会报错:
要避免key不存在的错误,有两种办法,一是通过in
判断key是否存在:
>>> 'Thomas' in d False
二是通过dict提供的get方法,如果key不存在,可以返回None,或者自己指定的value:
>>> d.get('Thomas') >>> d.get('Thomas', -1) -1
注意:返回None的时候Python的交互式命令行不显示结果。
要删除一个key,用pop(key)
方法,对应的value也会从dict中删除:
>>> d.pop('Bob') #有返回值 75 >>> d {'Michael': 95, 'Tracy': 85}
和list比较,dict有以下几个特点:
查找和插入的速度极快,不会随着key的增加而增加;
需要占用大量的内存,内存浪费多。
而list相反:
查找和插入的时间随着元素的增加而增加;
占用空间小,浪费内存很少。
所以,dict是用空间来换取时间的一种方法。
在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象。
这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key:
再议不可变对象
上面我们讲了,str是不变对象,而list是可变对象。
对于可变对象,比如list,对list进行操作,list内部的内容是会变化的,比如:
>>> a = ['c', 'b', 'a'] >>> a.sort()#使列表顺序颠倒 >>> a ['a', 'b', 'c']
而对于不可变对象,比如str,对str进行操作呢:
>>> a = 'abc' >>> a.replace('a', 'A') #有返回值 'Abc' >>> a 'abc'
使用key-value存储结构的dict在Python中非常有用,选择不可变对象作为key很重要,最常用的key是字符串。
函数 https://docs.python.org/2/library/functions.html#abs
求绝对值的函数abs
,只有一个参数
>>> abs(-20) 20
比较函数cmp(x, y)
就需要两个参数,如果x<y
,返回-1
,如果x==y
,返回0
,如果x>y
,返回1
:
>>> cmp(1, 2) -1
数据类型转换
Python内置的常用函数还包括数据类型转换函数,比如int()
函数可以把其他数据类型转换为整数:
>>> int('123') 123 >>> int(12.34) 12 >>> float('12.34') 12.34 >>> str(1.23) '1.23' >>> unicode(100) u'100' >>> bool(1) True >>> bool('') False
我们以自定义一个求绝对值的my_abs
函数为例:
def my_abs(x):if x >= 0:return xelse:return -x
如果参数类型不对,Python解释器就无法帮我们检查。试试my_abs
和内置函数abs
的差别:
>>> my_abs('A') 'A' >>> abs('A') Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: bad operand type for abs(): 'str'
当传入了不恰当的参数时,内置函数abs
会检查出参数错误,而我们定义的my_abs
没有参数检查,所以,这个函数定义不够完善。
让我们修改一下my_abs
的定义,对参数类型做检查,只允许整数和浮点数类型的参数。数据类型检查可以用内置函数isinstance
实现:
def my_abs(x):if not isinstance(x, (int, float)):raise TypeError('bad operand type')if x >= 0:return x else:return -x
添加了参数检查后,如果传入错误的参数类型,函数就可以抛出一个错误:
>>> my_abs('A') Traceback (most recent call last):File "<stdin>", line 1, in <module>File "<stdin>", line 3, in my_abs TypeError: bad operand type
定义函数时,需要确定函数名和参数个数;
如果有必要,可以先对参数的数据类型做检查;
函数体内部可以用return
随时返回函数结果;
函数执行完毕也没有return
语句时,自动return None
。
函数可以同时返回多个值,但其实就是一个tuple。
默认参数
定义默认参数要牢记一点:默认参数必须指向不变对象!
为什么要设计str、None这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。
可变参数
我们以数学题为例子,给定一组数字a,b,c……,请计算a2 + b2 + c2 + ……。
要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来,这样,函数可以定义如下:
def calc(numbers):sum = 0for n in numbers:sum = sum + n * nreturn sum
但是调用的时候,需要先组装出一个list或tuple:
>>> calc([1, 2, 3]) 14 >>> calc((1, 3, 5, 7)) 84
如果利用可变参数,调用函数的方式可以简化成这样:
>>> calc(1, 2, 3) 14 >>> calc(1, 3, 5, 7) 84
所以,我们把函数的参数改为可变参数:
def calc(*numbers):sum = 0for n in numbers:sum = sum + n * nreturn sum
定义可变参数和定义list或tuple参数相比,仅仅在参数前面加了一个*
号。在函数内部,参数numbers
接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:
>>> calc(1, 2) 5 >>> calc() 0
如果已经有一个list或者tuple,要调用一个可变参数怎么办?可以这样做:
>>> nums = [1, 2, 3] >>> calc(nums[0], nums[1], nums[2]) 14
这种写法当然是可行的,问题是太繁琐,所以Python允许你在list或tuple前面加一个*
号,把list或tuple的元素变成可变参数传进去:
>>> nums = [1, 2, 3] >>> calc(*nums) 14
这种写法相当有用,而且很常见。
关键字参数
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例:
def person(name, age, **kw):print 'name:', name, 'age:', age, 'other:', kw
函数person
除了必选参数name
和age
外,还接受关键字参数kw
。在调用该函数时,可以只传入必选参数:
>>> person('Michael', 30) name: Michael age: 30 other: {}
也可以传入任意个数的关键字参数:
>>> person('Bob', 35, city='Beijing') name: Bob age: 35 other: {'city': 'Beijing'} >>> person('Adam', 45, gender='M', job='Engineer') name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
参数组合
在Python中定义函数,可以用必选参数、默认参数、可变参数和关键字参数,这4种参数都可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。
比如定义一个函数,包含上述4种参数:
def func(a, b, c=0, *args, **kw):print 'a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw
在函数调用的时候,Python解释器自动按照参数位置和参数名把对应的参数传进去。
>>> func(1, 2) a = 1 b = 2 c = 0 args = () kw = {}
>>> func(1, 2, 3, 'a', 'b', x=99) a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
最神奇的是通过一个tuple和dict,你也可以调用该函数:
>>> args = (1, 2, 3, 4)>>> kw = {'x': 99}>>> func(*args, **kw) a = 1 b = 2 c = 3 args = (4,) kw = {'x': 99}
所以,对于任意函数,都可以通过类似func(*args, **kw)
的形式调用它,无论它的参数是如何定义的。
小结
Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。
默认参数一定要用不可变对象,如果是可变对象,运行会有逻辑错误!
要注意定义可变参数和关键字参数的语法:
*args
是可变参数,args接收的是一个tuple;
**kw
是关键字参数,kw接收的是一个dict。
以及调用函数时如何传入可变参数和关键字参数的语法:
可变参数既可以直接传入:func(1, 2, 3)
,又可以先组装list或tuple,再通过*args
传入:func(*(1, 2, 3))
;
关键字参数既可以直接传入:func(a=1, b=2)
,又可以先组装dict,再通过**kw
传入:func(**{'a': 1, 'b': 2})
。
使用*args
和**kw
是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
转载于:https://blog.51cto.com/pytho/1924492
记忆模糊知识点5-11相关推荐
- 地壳中元素含量排名记忆口诀_【中考化学】初中化学记忆性知识点03-生活中的化学-生活常识...
初中化学记忆性知识点03-生活中的化学-生活常识 空气主要成分 1.体积分数 氮气:78% 氧气:21% 稀有气体:0.94%-通电时会发出不同颜色光 二氧化碳:0.03% 2.空气污染 有害气体:常 ...
- 记忆模糊的知识点5-17
作用域 变量和作用域的示例:http://www.2cto.com/kf/201405/300359.html 关于函数的private :后续还需要深入了解 在一个模块中,我们可能会定义很多函数和 ...
- 记忆模糊、记忆泛化的关键分子开关被发现
来源:brainnews 2018年3月12日,Nature Medicine杂志在线刊登了麻省总医院Amar Sahay研究组的最新重要工作,他们发现了一种细胞骨架蛋白Actin-binding L ...
- Linux c/c++编程--知识点(11)errno,strerror
文章原文: 返回知识列表:Linux c/c++编程-- 知识点汇总 #include <errno.h> 声明了errno NAMEerrno - number of last err ...
- 概率论需要记忆的知识点
概率论 `明天要考试了,好慌 文章目录 概率论 前言 1.事件的运算及概率 2.全概率公式.贝叶斯公式 3.一维随机变量 4.五种重要分布 5.离散型二维随机变量 6.连续型二维随机变量 7.二维随机 ...
- 单招计算机考试知识点,单招考试数学必背知识点(11页)-原创力文档
2018 年单招考试<数学>必背知识点(一) 一.不为 0 的量 1.分式 A 中,分母 B≠0: 2.二次方程 ax2+bx+c=0( a≠0) B k( k≠0) 3.一次函数 y=k ...
- C++知识点(2022.11.26~2023.1.31已完结)
目录 一.数据的输入 二.数据的输出 三.内存分区模型 四.引用 五.函数(区别于C语言) 六.类和对象 七.C++文件操作 八.模板 8.1函数模板 8.2类模板 九.STL(Standard Te ...
- 【软件设计师】历年真题-模糊知识点备忘——15年上 上午真题
1.计算机中CPU对其访问速度最快的是 通用寄存器 . 2.总线宽度为32bit,时钟频率为200MHz,若总线上每5个时钟周期传送一个32bit的字,则该总线的带宽为 160 MB/S [解析]根据 ...
- Go 知识点(11) — goroutine 泄露、设置子协程退出条件
1. 问题现象 如果在开发过程中不考虑 goroutine 在什么时候能退出和控制 goroutine 生命期,就会造成 goroutine 失控或者泄露的情况 ,看示例代码: func consum ...
- ARM裸机的知识点总结---------11、iNandFlash (sd卡芯片化)
Author: 想文艺一点的程序员 自动化专业 工科男 再坚持一点,再自律一点 CSDN@想文艺一点的程序员 来自朱有鹏嵌入式的学习笔记 目录 一.iNand介绍 1.iNand /eMMC /SDC ...
最新文章
- Math类(工具类)
- Celery 源码解析六:Events 的实现
- Android 布局 优先显示右侧的控件
- 其实,我只想安静的写写代码...
- 【计算机基础】 经常使用的排序算法的时间复杂度和空间复杂度
- 2019牛客暑期多校训练营(第二场)-D Kth Minimum Clique
- lol更新显示正在连接服务器,wegame更新游戏显示正在连接服务器
- 本科生计算机论文中文核心,本科生可以发表核心期刊论文吗
- 腾讯启动校园招聘人才
- java中String xx xx_Java中常用String方法
- 使用bable打包js
- c# wifi串口通信_C#中的串口通信
- cisco路由器各接口模块代表的含义是什么
- iOS开发关于“发送原图”功能问题的记录
- C#学习之web网站制作入门篇(ASP.NET)
- 浅析智能化指挥信息系统发展
- cocos2d-js
- Couldn't resolve error at 'ntdll!NtOpenProcess'
- remap的困惑说明
- strategies
热门文章
- Two sum (bilibili有讲解视频)
- 求小球落地5次后所经历的路程和第5次反弹的高度
- html5仿微博弹出,JS 仿腾讯发表微博的效果代码
- 计算机操作系统详细学习笔记(二):处理器管理
- Moore-Penrose 广义逆
- jsp中使用jsp:include /在切换tomcat版本时遇到的问题
- 【jquery调用ajax老是进error,不进success】 bug命名:小雨
- call_user_func_array 调用回调函数
- 使用sudo apt-get出现无法解析域名的问题:“cn.archive.ubuntu.com”
- CISC 332*/CMPE 332* –Database Management Systems