学习资料
Python之旅
相关链接
Python 基础
笔记
常用数据类型
- 序列(suquence): Python 最基本的数据结构.
特点: 根据索引(index,即元素的位置)来获取序列中的元素
所有序列都可以进行的通用操作
索引(indexing)
分片(slicing)
迭代(iteration)
加(adding)
乘(multiplying) - 常用数据类型
列表(list): 属于序列
元祖(tuple): 属于序列
字符串(string): 属于序列
** 字典( dict)**: 属于映射类型,键值对构成
集合(set): 包含的所有元素不可重复
通用序列操作
索引 - index
用于通过位置获取序列中的单个元素
>>> nums = [1,2,3,4,5] #list, like array in swift
>>> nums[0]
1
>>> nums[4]
5
>>> nums[-1] # index -1 express the last factor
5
>>>
>>> s = 'asdfghjk' # string
>>> s[0]
'a'
>>> s[1]
's'
>>> a = (1,2,3) # tuple
>>> a[0]
1
>>>
ps: -1 代表序列的最后一个元素,-2代表倒数第二个元素,以此类推
分片 - slice
通过两个索引获取序列的部分元素
分片操作需要提供两个索引作为边界,中间用冒号相隔
>>> nums = [1,2,3,4,5,6,7] # list 分片
>>> nums[0:2]
[1, 2]
>>> nums[3:5]
[4, 5]
>>> s = 'Hello,world' # string 分片
>>> s[0:5]
'Hello'
>>> a = (2,3,5,6,7,77,6) # tuple 分片
>>> a[3:6]
(6, 7, 77)
ps: 分片的两个索引是半闭半开区间,第一个索引的元素包括,第二个索引的元素不包括
>>> nums[-3:] # 如果希望包含最后一个元素,可将第二个索引置为空
[5, 6, 7]
>>> nums[0:4:1] # 步长为1, 默认步长为1,可不写
[1, 2, 3, 4]
>>> nums[::3] # 如果要复制整个序列,可以将两个索引都置为空
[1, 4, 7]
>>>
>>> nums[0:4:-1] # 步长为负表示从右往左取元素, 因为左边元素比右边元素出现的晚(相较于从左到右的排列顺序),所以返回空
[]
>>> nums[4:0:-1]
[5, 4, 3, 2]
总结
- 左边索引的元素包括在结果之中,右边索引的元素不包括在结果之中
- 当使用一个负数作为步长时,必须让左边索引大于右边索引
- 对于正数步长,从左往右去元素,对于负数步长,从右往左取元素
加 - add
序列可以进行加法
操作
>>> [3,1,4] + [7,9] # 加法其实就是连接
[3, 1, 4, 7, 9]
>>> (1,2,3) + (9,6)
(1, 2, 3, 9, 6)
>>> 'hello' + 'world'
'helloworld'
>>> [1,2,3] + (1,2,3) # 相同的数据类型直接才可以做加法
Traceback (most recent call last):
File "", line 1, in
TypeError: can only concatenate list (not "tuple") to list
乘 - multiply
序列可以进行乘法
操作
>>> 'asd' * 3
'asdasdasd'
>>> [3]*4
[3, 3, 3, 3]
>>> [1,2,3] * 4
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
>>>
in
检查一个值是否在序列中
>>> 'he' in 'hello'
True
>>> 'hl' in 'hello'
False
>>> 10 in [4,6,10]
True
>>>
常用数据类型详解
列表 - list
- list 是 可变的(mutable),可以对它进行随意修改. string 和 tuple 是不可变的
string/tuple 转 list
>>> s = 'hello'
>>> list(s)
['h', 'e', 'l', 'l', 'o']
>>> t = (1,2,3,4)
>>> list(t)
[1, 2, 3, 4]
- 常用的列表方法
- index: 用于从列表中找出某个元素的位置,如果多个相同的元素,则返回第一个元素的位置, 如果没有找到元素则会抛出异常
>>> nums = [1,2,3,4,5,7,8,9,5]
>>> nums.index(3)
2
>>> nums.index(5)
4
>>> words = ['hello','world','me','her','he']
>>> words.index('he')
4
>>> words.index('him')
Traceback (most recent call last):
File "", line 1, in
ValueError: 'him' is not in list
- count: 用于统计某个元素在列表中出现的次数
>>> nums = [1,2,2,2,3,4,5,3,4,7,8,9]
>>> nums.count(2)
3
>>> nums.count(4)
2
>>> nums.count(10) # 没有该元素返回 0
0
>>>
- append: 在列表末尾增加新元素
>>> nums = [1,2,2,2,3,4,5,3,4,7,8,9]
>>> nums.append(100)
>>> nums
[1, 2, 2, 2, 3, 4, 5, 3, 4, 7, 8, 9, 100]
>>> nums.append([1000,9000]) # 将[1000,9000]作为一个元素加入 nums
>>> nums
[1, 2, 2, 2, 3, 4, 5, 3, 4, 7, 8, 9, 100, [1000, 9000]]
- extend: 将一个新列表的元素添加到原列表中
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> a.extend(b)
>>> a
[1, 2, 3, 4, 5, 6]
ps: append 与 extend 都可接收一个列表作为参数. append是将其作为一个元素加入到列表,而 extend 是将新列表的元素逐个加入到原列表中
- insert: 将某个元素加入到某个位置
>>> nums = [1,2,3,4,5,6,8]
>>> nums.insert(3,10) # arg1: 插入位置 arg2: 插入元素
>>> nums
[1, 2, 3, 10, 4, 5, 6, 8]
- pop: 移除列表中的一个元素(默认最后一个), 并且返回该元素的值
>>> nums = [1,2,3,4,5,6,8]
>>> nums.insert(3,10)
>>> nums
[1, 2, 3, 10, 4, 5, 6, 8]
>>> nums.pop()
8
>>> nums.pop(3) # arg: 移除元素的 index
10
>>> nums
[1, 2, 3, 4, 5, 6]
- remove: 移除列表中某个匹配元素,如果多个匹配,则移除第一个,没有匹配元素抛出异常
>>> nums = [1,2,3,4,5,6,7,8,9]
>>> nums.append(5)
>>> nums
[1, 2, 3, 4, 5, 6, 7, 8, 9, 5]
>>> nums.remove(5)
>>> nums
[1, 2, 3, 4, 6, 7, 8, 9, 5]
>>> nums.remove(10)
Traceback (most recent call last):
File "", line 1, in
ValueError: list.remove(x): x not in list
>>>
- reverse: 将列表元素进行反转
>>> nums
[1, 2, 3, 4, 6, 7, 8, 9, 5]
>>> nums.reverse()
>>> nums # 改变了 nums
[5, 9, 8, 7, 6, 4, 3, 2, 1]
- sort: 对列表进行排序, 会改变原来的列表,而不是返回新的排序列表,另外, sort 方法返回值是空.若不想改变原列表,只希望返回一个排序后的列表,可以使用 sorted. 同时,
sort
和sorted
都是默认升序排列的,如果想要根据某种规则排序,可以指定排序参数.
>>> a = [4,3,2,1,69,6,7,0,88]
>>> b = a.sort()
>>> b == None
True
>>> a
[0, 1, 2, 3, 4, 6, 7, 69, 88]
>>> a.append(8)
>>> a
[0, 1, 2, 3, 4, 6, 7, 69, 88, 8]
>>> c = sorted(a)
>>> c
[0, 1, 2, 3, 4, 6, 7, 8, 69, 88]
>>> a
[0, 1, 2, 3, 4, 6, 7, 69, 88, 8]
>>> a.sort(reverse = True) # reverse 关键字
>>> a
[88, 69, 8, 7, 6, 4, 3, 2, 1, 0]
>>> a.append(99)
>>> a
[88, 69, 8, 7, 6, 4, 3, 2, 1, 0, 99]
>>> d = sorted(a,reverse = True) # sorted 逆序
>>> d
[99, 88, 69, 8, 7, 6, 4, 3, 2, 1, 0]
>>> a
[88, 69, 8, 7, 6, 4, 3, 2, 1, 0, 99]
其他排序规则
>>> s = ['ccc','a','bb','dddd']
>>> s.sort(key=len) # key: 关键字参数, len: 键参数,根据元素长度排序
>>> s
['a', 'bb', 'ccc', 'dddd']
使用 sorted 进行队列排序
>>> students =
[('john','B',15),
('jane','A',12),
('dave','B',10),
('ethan','C',20),
('peter','B',20),
('mike','C',16)]
>>> b = orted(students, key=lambda student:student[2]) # arg1: 要排序的 list, arg2:排序规则 - 对第三列从小到大排序
>>> b
[('dave', 'B', 10),
('jane', 'A', 12),
('john', 'B', 15),
('mike', 'C', 16),
('ethan', 'C', 20),
('peter', 'B', 20)]
>>> c = sorted(students, key=lambda student:(student[1],-student[2])) # 对第二列从小到大排序,再对第三列从大到小排序
>>> c
[('jane', 'A', 12),
('peter', 'B', 20),
('john', 'B', 15),
('dave', 'B', 10),
('ethan', 'C', 20),
('mike', 'C', 16)]
>>>
PS: 更多排序知识
元组 - tuple
不可变的序列
>>> a = (1,2,3)
>>> a
(1, 2, 3)
>>> a[0]
1
>>> a[0] = 6
Traceback (most recent call last):
File "", line 1, in
TypeError: 'tuple' object does not support item assignment
>>>
>>> b = () # 空元组
>>> b
()
>>> c = (12,) # 创建一个值的元组要在值的后面再加一个逗号
>>> c
(12,)
>>> type(c)
>>> d = (12) # 不加`,`只使用括号不是元组,本质是 d = 12
>>> d
12
>>> type(d)
ps:创建一个值的元组要在值的后面再加一个逗号
字符串 - string
也是序列,index, slice, add, multiply 同样适用
>>> s = 'python'
>>> s[0]
'p'
>>> s[1:3]
'yt'
>>> new = s + '2.7.10'
>>> new
'python2.7.10'
>>> mul = s * 3
>>> mul
'pythonpythonpython'
同时, string 是不可变序列, the same as tuple
>>> s[1] = 'h'
Traceback (most recent call last):
File "", line 1, in
TypeError: 'str' object does not support item assignment
字符串特有的方法
以下是一些常用的方法
- find : 在一个字符串中查找子串,返回子串所在所在位置的最左端的索引,没有则返回-1
>>> pt = 'I am learning python without eating'
>>> pt.find('am')
2
>>> py = "listen music in the week"
>>> py.find('in')
13
>>> py.find('mu',4) # 指定寻找的起始位置
7
>>> py.find('en',4,10) # 指定寻找的起始和终止位置,没有找到,返回-1
4
- split : 将字符串分割成序列
>>> s = 'Libe is my niece and she is learning in new zealand'
>>> s.split() # 不提供分隔符,则默认会使用所有空格作为分隔符(空格,制表符,换行等)
['Libe', 'is', 'my', 'niece', 'and', 'she', 'is', 'learning', 'in', 'new', 'zealand']
>>> s.split('a')
['Libe is my niece ', 'nd she is le', 'rning in new ze', 'l', 'nd']
>>>
- join : split 的逆方法,用来将序列中的元素连接起来
>>> '+'.join(s.split('a'))
'Libe is my niece +nd she is le+rning in new ze+l+nd'
>>> ''.join(['h','e','ll','o'])
'hello'
>>> '+'.join([1,2,3,4]) # 不能是数字
Traceback (most recent call last):
File "", line 1, in
TypeError: sequence item 0: expected string, int found
- strip : 用于移除字符串左右两侧的空格,但不包括内部,当然也可以指定需要移除的字符串
>>> ' hello world! '.strip() # 移除两侧的空格
'hello world!'
>>> '%%% hello world!!! #####'.strip('%#') # 移除左右两侧的%或者#
' hello world!!! '
>>> '%%% hello world!!! #####'.strip('%# ') # 移除左右两侧的%或者#或空格
'hello world!!!'
- replace : 替换字符串中所有的匹配项
>>> typo = 'It is so difficult for me to remeber this word'
>>> typo.replace('to','TO') # arg1: 将要被替换的字符串 arg2: 用来替换的字符串, 返 一个新的字符串
'It is so difficult for me TO remeber this word'
>>> typo # 原字符串不变
'It is so difficult for me to remeber this word'
- translate : 替换字符串中的某些部分,但只能处理单个字符
>>> from string import maketrans
>>> table = maketrans('aeiou','12345')
>>> metto = 'to be or not to be, that is a question'
>>> metto.translate(table)
't4 b2 4r n4t t4 b2, th1t 3s 1 q52st34n'
>>> metto
'to be or not to be, that is a question'
>>> metto.translate(table, 'rqu') # 移除所有的'r','q','u'
't4 b2 4 n4t t4 b2, th1t 3s 1 2st34n'
说明
maketrans 接收两个参数:两个等长的字符串,表示第一个字符串的每个字符用第二个字符串对应位置的字符替代,在上面的例子中,就是 'a' 用 '1' 替代,'e' 用 '2' 替代,等等.字符的代替,而不是整个字符串的替代。因此,motto 中的 o 都被替换为 4,e 都被替换为 2,等等。
- lower/upper : 返回字符串的大写或小写形式
>>> x = 'PPYHFMF'
>>> x.lower()
'ppyhfmf'
>>> x
'PPYHFMF'
>>> y = 'python'
>>> y.upper()
'PYTHON'
>>> y
'python'
总结
- 字符串是不可变对象,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回。
- translate 针对单个字符进行替换
字典 - dict
Python 中唯一的映射类型. 由 key-value构成. key 必须是不可变的类型,比如数字,字符串和元组
创建字典
>>> d0 = {} # 空字典
>>> d0
{}
>>> d1 = {'name': 'roni', 'age':23}
>>> d1
{'age': 23, 'name': 'roni'}
>>> d1['age']
23
>>> d1['age'] = 26 # update dic
>>> d1['age']
26
>>> d2 = dict(name = 'devzheng', age = 24)
>>> d2
{'age': 24, 'name': 'devzheng'}
>>> item = [('name','wqrr'),('age', 99)]
>>> d3 = dict(item) # 函数
>>> d3
{'age': 99, 'name': 'wqrr'}
遍历字典
>>> d = {'name': 'roni', 'age':23}
>>> for key in d:
... print('%s:%s' % (key, d[key]))
...
age:23
name:roni
>>> for key in d: # 冒号后,下行最前面要打空格
... if key == 'roni': # 冒号后,下行前面打tab + 空格
... del d[key]
File "", line 3
del d[key]
^
IndentationError: expected an indented block # Python 真蛋疼
>>> for key in d:
... if key == 'name':
... del d[key] # 这样删会出错
...
Traceback (most recent call last):
File "", line 1, in
RuntimeError: dictionary changed size during iteration
>>> for key in d.keys(): # 要删除,Python2中这样, Python3中使用 list(d.keys())
... if key == 'name':
... del d[key]
...
>>> d
{'age': 23}
```
##### 判断键是否在字典中
```
>>> d = {'name': 'roni', 'age':23}
>>> 'name' in d
True
>>> d['s'] # key net exsit , throw error 'keyError'
Traceback (most recent call last):
File "", line 1, in
KeyError: 's'
>>> 's' in d
False
```
##### dict 常用方法
1. **clear**: 清空字典中的所有项,无返回值(None)
```
>>> d = {'name': 'roni', 'age':23}
>>> d.clear()
>>> d
{}
>>> d = {'name': 'roni', 'age':23}
>>> c = d.clear()
>>> d
{}
>>> print c
None
```
```
>>> d1 = {}
>>> d2 = d1
>>> d2
{}
>>> d2['name'] = 'roni'
>>> d2
{'name': 'roni'}
>>> d1 # d1 中的内容也变了,共用了一段地址
{'name': 'roni'}
>>> d1 = {} # 置空,重新分配了地址,d2内容不变
>>> d1
{}
>>> d2 # 未变
{'name': 'roni'}
>>> d3 = d2
>>> d3
{'name': 'roni'}
>>> d2.clear() # 清空地址中的内容, d3 和 d2 共用一段地址, 所以 d3 也会变空
>>> d2
{}
>>> d3
{}
```
2. **copy**: 浅复制(shadow copy)
* 对可变对象的修改保持同步
* 对不可变对象的修改保持独立
`浅复制 shadow copy`
```
>>> d1 = {'name': 'roni', 'books': ['book1','book2', 'book3']}
>>> d2 = d1.copy()
>>> d2
{'books': ['book1', 'book2', 'book3'], 'name': 'roni'}
>>> d2['name'] = 'wqrr' # string 不可变, 修改保持独立
>>> d2
{'books': ['book1', 'book2', 'book3'], 'name': 'wqrr'}
>>> d1 # 不变
{'books': ['book1', 'book2', 'book3'], 'name': 'roni'}
>>> d2['books'].remove('book2') # list 是可变的, 修改保持同步
>>> d2
{'books': ['book1', 'book3'], 'name': 'wqrr'}
>>> d1
{'books': ['book1', 'book3'], 'name': 'roni'}
>>> d1['books'].remove('book1')
>>> d1
{'books': ['book3'], 'name': 'roni'}
>>> d2
{'books': ['book3'], 'name': 'wqrr'}
```
`深复制 deep copy: 创造副本, 新地址,与原对象没有关系`
```
>>> from copy import deepcopy
>>> d5 = deepcopy(d1)
>>> d5
{'books': ['book3'], 'name': 'roni'}
>>> d1['books'].append('book4') # d1的任何修改都不影响 d5
>>> d1
{'books': ['book3', 'book4'], 'name': 'roni'}
>>> d5
{'books': ['book3'], 'name': 'roni'}
>>> d1['name'] = '11'
>>> d1
{'books': ['book3', 'book4'], 'name': '11'}
>>> d5
{'books': ['book3'], 'name': 'roni'}
```
3. **get**:
```
>>> d = {'name': 'roni', 'books': ['book1','book2', 'book3']}
>>> d['nnn'] # 无 key 报错
Traceback (most recent call last):
File "", line 1, in
KeyError: 'nnn'
>>> print d.get('nnn') # 不会报错
None
>>> print d.get('name')
roni
>>> d.get('nnn', 'wqrr') # arg1: 要取得 key, arg2: 未取到值时的默认值
'wqrr'
```
4. **setdefault**: 用于对字典设定键值. 使用形式: `dict.setdefault(key, default=None) `
```
>>> d = {}
>>> d.setdefault('name', 'roni') # key is not exsit, update dict
'roni'
>>> d
{'name': 'roni'}
>>> d['age'] = 25
>>> d
{'age': 25, 'name': 'roni'}
>>> d.setdefault('age', 18) # key is exsit, return original value, do not update dic
25
```
5. **update**: 用于将一个字典添加到原字典中,如果存在相同的键则会覆盖
```
>>> d = {}
>>> d1 = {'name': 'roni'}
>>> d.update(d1)
>>> d
{'name': 'roni'}
>>> d2 = {'name': 'wqrr'}
>>> d.update(d2)
>>> d
{'name': 'wqrr'}
```
6. **pop**: 用于将某个键值对从字典中移除,并返回 `给定键 ` 的值
```
>>> d.pop('name')
'wqrr'
>>> d
{}
```
7. **popitem**: 随机移除字典中的某个键值对, 返回移除的键值对
```
>>> d = {'name': 'roni', 'books': ['book1','book2', 'book3']}
>>> d.popitem()
('books', ['book1', 'book2', 'book3'])
>>> d
{'name': 'roni'}
```
8. **keys/iterkeys**: keys 将字典的键以列表形式返回, iterkeys 则返回针对键的迭代器
```
>>> d = {'name': 'roni', 'books': ['book1','book2', 'book3']}
>>> d.keys()
['books', 'name']
>>> d.iterkeys()
```
9. **values/itervalues**: values 将字典的值以列表形式返回, itervalues 则返回针对值得迭代器
```
>>> d.values()
[['book1', 'book2', 'book3'], 'roni']
>>> d.itervalues()
```
10. **items/iteritems**: items 将所有字典项以列表形式返回,这些列表项的每一项都来自于(key, value). iteritems 作用大致相同,但返回一个迭代器而不是列表. **对字典进行遍历, 推荐使用 iteritems**
```
>>> d.items()
[('books', ['book1', 'book2', 'book3']), ('name', 'roni')]
>>> for k,v in d.items():
... print('%s:%s' % (k, v))
...
books:['book1', 'book2', 'book3']
name:roni
>>> d.iteritems()
>>> for k,v in d.iteritems(): #推荐遍历方法
... print('%s: %s' % (k, v))
...
books: ['book1', 'book2', 'book3']
name: roni
```
##### 对元素为字典的列表排序
```
>>> students = [{'age': 12, 'name': 'jane', 'score': 'A'}, {'age': 15, 'name': 'john', 'score': 'B'}, {'age': 10, 'name': 'dave', 'score': 'B'}, {'age': 20, 'name': 'peter', 'score': 'B'}, {'age': 20, 'name': 'ethan', 'score': 'C'}, {'age': 16, 'name': 'mike', 'score': 'C'}]
>>> sorted(students, key = lambda stu: stu['score']) # 按 score 从小到大排序
[{'age': 12, 'score': 'A', 'name': 'jane'}, {'age': 15, 'score': 'B', 'name': 'john'}, {'age': 10, 'score': 'B', 'name': 'dave'}, {'age': 20, 'score': 'B', 'name': 'peter'}, {'age': 20, 'score': 'C', 'name': 'ethan'}, {'age': 16, 'score': 'C', 'name': 'mike'}]
>>> sorted(students, key = lambda stu: stu['score'], reverse=True) # 按 score 从大到小排序
[{'age': 20, 'score': 'C', 'name': 'ethan'}, {'age': 16, 'score': 'C', 'name': 'mike'}, {'age': 15, 'score': 'B', 'name': 'john'}, {'age': 10, 'score': 'B', 'name': 'dave'}, {'age': 20, 'score': 'B', 'name': 'peter'}, {'age': 12, 'score': 'A', 'name': 'jane'}]
>>> sorted(students, key = lambda stu: (stu['score'], -stu['age'])) # 按 score 从小到大,再按 age 从大到小
[{'age': 12, 'score': 'A', 'name': 'jane'}, {'age': 20, 'score': 'B', 'name': 'peter'}, {'age': 15, 'score': 'B', 'name': 'john'}, {'age': 10, 'score': 'B', 'name': 'dave'}, {'age': 20, 'score': 'C', 'name': 'ethan'}, {'age': 16, 'score': 'C', 'name': 'mike'}]
```
#### 集合 - set
一组 key 的集合, key 不能重复
##### 创建集合
```
>>> s = {'a', 'b', 'c', 'd', 'e'}
>>> s
set(['a', 'c', 'b', 'e', 'd'])
>>> s2 = set(['hello']) # 使用 set() 接收一个列表
>>> s2
set(['hello'])
>>> s3 = set(['h', 'e', 'll','e'])
>>> s3
set(['h', 'll', 'e'])
```
##### 遍历集合
```
>>> for e in s3:
... print(e)
...
h
ll
e
```
##### 添加元素
add() 方法将元素添加到 set 中,可以重复添加,但没有效果
```
>>> s3.add('o')
>>> s3
set(['h', 'll', 'e', 'o'])
>>> s3.add('o')
>>> s3
set(['h', 'll', 'e', 'o'])
```
##### 删除元素
remove()
```
>>> s3.remove('ll')
>>> s3
set(['h', 'e', 'o'])
>>> s3.remove('ll') # key is not exsit, keyError
Traceback (most recent call last):
File "", line 1, in
KeyError: 'll'
```
##### 交集/并集/差集
```
>>> s1 = {1,2,3,4,5,6}
>>> s2 = {4,5,6,7,8}
>>> s1 & s2 # 交集
set([4, 5, 6])
>>> s1 | s2 # 并集
set([1, 2, 3, 4, 5, 6, 7, 8])
>>> s1 - s2 # 差集
set([1, 2, 3])
>>> s3 = {1,2,3}
>>> s3.issubset(s1) # s3 是不是 s1 的子集
True
>>> s3.issubset(s2)
False
>>> s1.issuperset(s3) # # s1 是不是 s3 的超集
True
>>> s1.issuperset(s2)
False
```
***
#### 说明
PS: 以上内容均来自[Python之旅](http://funhacks.net/explore-python/).这里只是个人笔记.