入门
变量和基础类型
数据类型
- 整数 十六进制:0x
- 浮点数 1.23e4
- 字符串 ‘xxx’ 或 “xxx”
- 布尔值 True、False and、or、not
- 空值 None(不能理解为0)
1 | print '1 + 2=', 1 + 2 # 1 + 2 = 3 结束后自动换行 |
变量
大小写英文、数字、下划线,且不能是数字开头
1 | a = 1 |
变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。
字符串
####常见字符串
如果字符串包含单引号'
,则要用双引号""
括起来
如果既包含单引号又包含双引号,就要用反斜杠\
来转义
####raw字符串
如果一个字符串有很多要转义的字符,可以加个前缀r
,表示这是一个raw字符串,里面的字符就不需要转义了。例如:
1 | r'\(~_~)/ \(~_~)/' |
但是r'...'
表示法不能表示多行字符串,也不能表示包含'
和 "
的字符串
####多行字符串
如果要表示多行字符串,可以用'''...'''
表示(同样可以在前面加一个r):
1 | '''Line 1 |
上面这个字符串的表示方法和下面的是完全一样的:
1 | 'Line 1\nLine 2\nLine 3' |
Unicode字符串
最早的Python只支持ASCII编码,普通的字符串’ABC’在Python内部都是ASCII编码的。
Python在后来添加了对Unicode的支持,以Unicode表示的字符串用u’…’表示,比如:
1 | print u'中文' # 中文 |
注意: 不加 u ,中文就不能正常显示。
除了多了一个u
之外,与普通字符串没啥区别,转义字符和多行表示法仍然有效
如果中文字符串在Python环境下遇到 UnicodeDecodeError,这是因为.py文件保存的格式有问题。可以在第一行添加注释
1 | # -*- coding: utf-8 -*- |
整数与浮点数
同C语言:
- 整数 + 浮点数 = 浮点数
- 整数 / 整数 = 整数
- 整数 / 浮点数 = 浮点数
List 与 Tuple 类型
###list
1 | classmates = ['Michael', 'Bob', 'Tracy'] |
####倒序访问
1 | print L[0] # 索引从 0 开始 |
添加元素
1 | L.append('Paul') # 添加到尾部 |
删除元素
1 | L.pop() # 删除最后一个并返回这个元素 |
替换元素
1 | L[-1] = 'Paul' |
字符串list 首字母大写
1 | c = ['zz','yy','xx'] |
tuple
即不可变的 list
1 | t = () # 空tuple |
1 | t = ('Adam', 'Lisa', 'Bart') |
tuple和list外观唯一不同之处是用( )
替代了[ ]
tuple没有 append()方法,也没有insert()和pop()方法
####单元素tuple
1 | t = (1) # 这是整数 1,而不是tuple |
1 | t = (1,) # 可以加一个逗号","避免歧义 |
多元素 tuple 加不加这个额外的“,”效果是一样的:
1 | t = (1, 2, 3,) |
“可变”的 tuple
1 | t = ('a', 'b', ['A', 'B']) |
tuple所谓的“不变”是说,tuple的每个元素,指向永远不变。即指向’a’,就不能改成指向’b’,指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!
条件判断与循环
if - elif - else
if 语句后接表达式,然后用:
表示代码块开始。
注意: elif 和 else 后面有个 “:”
1 | age = 20 |
注意: **Python代码的缩进规则**。具有相同缩进的代码被视为代码块
缩进请严格按照Python的习惯写法:4个空格,不要使用Tab,更不要混合Tab和空格,否则很容易造成因为缩进引起的语法错误。
如果你在Python交互环境下敲代码,还要特别留意缩进,并且退出缩进需要多敲一行回车
循环
1 | L = ['Adam', 'Lisa', 'Bart'] |
1 | N = 10 |
循环控制
- break
- continue
Dict 和 Set 类型
###Dict
{ key : value }
1 | d = { |
判断 key 是否存在:
1 | if 'Paul' in d: |
dict 的 get 方法:在 Key 不存在的时候返回 None
1 | print d.get('Bart') # 59 |
Dict 的特点
dict的第一个特点是查找速度快,无论dict有10个元素还是10万个元素,查找速度都一样
dict的缺点是占用内存大,还会浪费很多内容,list正好相反,占用内存小,但是查找速度慢。
由于dict是按 key 查找,所以,在一个dict中,key不能重复。
dict的第二个特点就是存储的key-value序对是没有顺序的!这和list不一样
打印的顺序不一定是我们创建时的顺序
dict的第三个特点是作为 key 的元素必须不可变:可变的 list 不能作为 key
1 | { |
更新 dict
1 | d['Paul'] = 72 |
如果 key 已经存在,则赋值会用新的 value 替换掉原来的 value
####遍历 dict
1 | d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } |
set
dict的作用是建立一组 key 和一组 value 的映射关系,dict的key是不能重复的。
set 持有一系列元素,这一点和 list 很像,但是set的元素没有重复,而且是无序的,这点和 dict 的 key很像。
创建 set 的方式是调用 set() 并传入一个 list,list的元素将作为set的元素:
1 | s = set(['A', 'B', 'C', 'A']) |
####访问 set
1 | s = set(['Adam', 'Lisa', 'Bart', 'Paul']) |
set 的特点
key必须是不变对象
判断一个元素是否在set中速度很快
set存储的元素也是没有顺序的
遍历 set
1 | s = set(['Adam', 'Lisa', 'Bart']) |
更新 set
1 | s.add('Adam') # 如果添加的元素已经存在,不会报错,但是不会加进去了 |
函数
内置函数
1 | int('123') # 转换到整数 |
自定义函数
1 | def my_abs(x): |
return None可以简写为return
多返回值
1 | import math |
但其实这只是一种假象,Python函数返回的仍然是单一值
用print打印返回结果,原来返回值是一个tuple!
在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值
递归函数
1 | def fact(n): |
使用递归函数需要注意防止栈溢出
默认参数
1 | int('123', 8) # 83 两个参数的int:10进制转到8进制 |
1 | def power(x, n=2): # 求幂,默认平方 |
由于函数的参数按从左到右的顺序匹配,所以默认参数只能定义在必需参数的后面
可变参数
1 | def fn(*args): |
可变参数的名字前面有个 *** **号
解释器会把传入的一组参数组装成一个tuple传递给可变参数,直接把变量 args 看成一个 tuple 就好了
切片
对list进行切片
1 | L[0:3] # 取前3个元素:['Adam', 'Lisa', 'Bart'] |
L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素。
如果第一个索引是0,还可以省略:
1 | L[:3] # 前三个 |
切片操作还可以指定第三个参数:
1 | L[::2] # 表示每N个取一个 |
把list换成tuple,切片操作完全相同,只是切片的结果也变成了tuple。
倒序切片
1 | L = ['Adam', 'Lisa', 'Bart', 'Paul'] |
记住倒数第一个元素的索引是-1。倒序切片包含起始索引,不包含结束索引。
字符串切片
1 | 'ABCDEFG'[:3] # 'ABC' |
1 | 'abc'.upper() # 所有字母变大写 'ABC' |
迭代
就是遍历
Python 的 for循环不仅可以用在list或tuple上,还可以作用在其他任何可迭代对象上
索引迭代
在 for 循环中拿到索引:enumerate() 函数 ,绑定索引index和元素name
1 | L = ['Adam', 'Lisa', 'Bart', 'Paul'] |
输出结果是:
1 | 0 - Adam |
实际上,enumerate() 函数把:
1 | ['Adam', 'Lisa', 'Bart', 'Paul'] |
变成了类似:
1 | [(0, 'Adam'), (1, 'Lisa'), (2, 'Bart'), (3, 'Paul')] |
因此,迭代的每一个元素实际上是一个tuple:
1 | for t in enumerate(L): |
如果我们知道每个tuple元素都包含两个元素,for循环又可以进一步简写为:
1 | for index, name in enumerate(L): # 最初的式子 |
额外:zip()函数
zip()函数可以把两个 list 变成一个 list:
1 | zip([10, 20, 30], ['A', 'B', 'C']) |
迭代dict的value
dict 对象有一个 values() 方法:把dict转换成一个包含所有value的list,这样,我们迭代的就是 dict的每一个 value:
1 | d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } |
dict除了values()方法外,还有一个itervalues() **方法,用itervalues()** 方法替代 values() 方法,迭代效果完全一样:
1 | d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } |
那这两个方法有何不同之处呢?
values() 方法实际上把一个 dict 转换成了包含 value 的list。
但是 itervalues() 方法不会转换,它会在迭代过程中依次从 dict 中取出 value,所以 itervalues() 方法比 values() 方法节省了生成 list 所需的内存。
打印 itervalues() 发现它返回一个 <dictionary-valueiterator> 对象,这说明在Python中,for 循环可作用的迭代对象远不止 list,tuple,str,unicode,dict等,任何可迭代对象都可以作用于for循环,而内部如何迭代我们通常并不用关心。
如果一个对象说自己可迭代,那我们就直接用 for 循环去迭代它,可见,迭代是一种抽象的数据操作,它不对迭代对象内部的数据有任何要求。
迭代dict的key和value
1 | d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } |
1 | for key, value in d.items(): |
和 values() 有一个 itervalues() 类似, items() *也有一个对应的 *iteritems(),iteritems() 不把dict转换成list,而是在迭代过程中不断给出 tuple,所以, iteritems() 不占用额外的内存。
列表生成式
生成列表
1 | # 生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] |
1 | # 生成[1x1, 2x2, 3x3, ..., 10x10] (方式一:循环)(繁琐) |
1 | # 生成[1x1, 2x2, 3x3, ..., 10x10] (方式二:列表生成式) |
复杂表达式
假设有如下的dict:
1 | d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } |
完全可以通过一个复杂的列表生成式把它变成一个 HTML 表格:
1 | tds = ['<tr><td>%s</td><td>%s</td></tr>' % (name, score) for name, score in d.iteritems()] |
注:字符串可以通过 % 进行格式化,用指定的参数替代%s。字符串的join()方法可以把一个 list 拼接成一个字符串。
条件过滤
for 循环后面可以加上 if 判断
1 | [x * x for x in range(1, 11) if x % 2 == 0] |
有了 if 条件,只有 if 判断为 True 的时候,才把循环的当前元素添加到列表中。
多层表达式
对于字符串 ‘ABC’ 和 ‘123’,可以使用两层循环,生成全排列:
1 | for m in 'ABC' for n in '123'] [m + n |
翻译成循环代码就像下面这样:
1 | L = [] |