一.切片
本质上就是js中的slice方法,只不过表达形式上有所不同,一样的是这是一个纯函数
有以下几种形式
# 使用 [:] 这种形式表示切片
[startIndex=0:endIndex=len(list)]
# 每隔几个数取一个值 [::]
[startIndex=0::numToSkip-1]
# 这种情况当为-1时,会反向元素 !!!(小技巧)
# 取区域内的元素,然后每隔几个取一个
[startIndex=0:endIndex=len(list):numToSkip-1]
具体示例
# 普通的slice
>>> L = list(range(1, 100, 2)) # 即1-100之间的奇数组成的list
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37,
39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71,
73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]
# 复制整个list, 直接[:]
>>> anotherList = L[:]
# 复制部分的list
# 索引为2开始到10(不包含)
>>> partList = L[2:10]
[5, 7, 9, 11, 13, 15, 17, 19]
# 从40开始, 默认到最后
>>> partList = L[40:]
[81, 83, 85, 87, 89, 91, 93, 95, 97, 99]
# 默认从0开始
>>> partList = L[:10]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
# 从后开始 -1为最后一个
>>> partList = L[-5:-1]
[91, 93, 95, 97]
# 后2个数
>>> partList = L[-2:]
[97, 99]
# 每隔几个数取一个
# 每隔(5 - 1) = 4个取一个
>>> L[::5]
[1, 11, 21, 31, 41, 51, 61, 71, 81, 91]
# 前10个每隔1个取一个
>>> L[:10:2]
[1, 5, 9, 13, 17]
>>> L[3:10:2]
[7, 11, 15, 19]
同样 tuple 类型 和 str 类型也可以使用切片
>>> (1, 2, 3, 4)[:3]
(1, 2, 3)
>>> s = 'ABCDEFG'
>>> s[:3]
'ABC'
>>> s[::2]
'ACEG'
# 取-1时将字符串反向
>>> s[::-1]
'GFEDCBA'
# [::-2] 则是先反向,然后每隔(2-1)个取一个值
>>> s[::-2]
'GECA'
二.迭代
python中对可迭代对象都可以使用 for...in 进行迭代操作
如何判断一个对象是否可迭代,可以使用python提供的 collections 集合中的 'isinstance' 方法,查看是否属于 Iterable
的实例
from collections import Iterable
# 对字符串str类型
>>> isinstance('abc', Iterable)
True
# 对list类型
>>> isinstance([1, 2, 3], Iterable)
True
# 对字典dict类型
>>> isinstance({'a': 1, 'b': 2}, Iterable)
True
# 对数值类型
>>> isinstance(123, Iterable)
False
字典dict 迭代
对于字典类型(dict), 可以使用 items()
, values()
方法对值或实体进行迭代
>>> d = {'a': 1, 'b': 2, 'c': 3}
# 直接对键进行迭代
# 因为字典是无序的,所以输出顺序不一定
>>> for key in d:
... print(key)
a
c
b
# 对值进行迭代 values()
>>> for value in d.values():
... print(value)
3
2
1
# 对键值对进行迭代 items()
>>> for k, v in d.items():
... print(k, '', v)
'a' 1
'b' 2
'c' 3
list 带索引迭代
对于list要将索引也显示出来,则可以使用python内置的 enumerate()
函数将list变为 索引-值 对
>>> for i, value in enumerate(['A', 'B', 'C']):
... print(i, value)
0 A
1 B
2 C
字符串str 迭代
>>> for ch in 'ABC':
... print(ch)
A
B
C
for 循环同时引用2个变量
python中比较常见
>>> for x, y in [(1, 1), (2, 4), (3, 9)]:
... print(x, y)
1 1
2 4
3 9
三.列表生成式 (list comprehensions)
快速生成一个list的简写方式
比如要生成一个这样的list:
[1*1, 2*2, 3*3, 4*4, ..., 10*10]
一般写法为:
>>> L = []
>>> for x in range(1, 11):
... L.append(x * x)
使用列表生成式,可以写为:
>>> [x * x for x in range(1, 11)]
将要生成的元素 x*x
放在前面, 后面跟着for循环即可
还可以在for后面添加条件:
# 只对偶数平方
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
可以添加2层循环
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
将dict生成一个list:
>>> d = {'x': 'A', 'y': 'B', 'z': 'C'}
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']
使用 lower()
方法将列表中的字符串都变为小写; title()
将字符串首字母大写
>>> L = ['Hello', 18, 'World']
>>> [s.lower() for s in L if isinstance(s, str)]
['hello', 'world']
另外可想而知,转换为大写的方法为 upper()
四.生成器 generator
好吧,每种语言都是相似的,python中也存在生成器,上面的列表生成式,将'[]' 改为 '()' 即可产生一个generator对象
>>> L = [x * x for x in range(10) if x % 2 == 0]
>>> L
[0, 4, 16, 36, 64]
# 生成一个generator对象
>>> g = (x * x for x in range(10) if x % 2 == 0)
>>> g
<generator object <genexpr> at 0x1022ef630>
生成器的方法 next()
>>> next(g)
0
>>> next(g)
4
>>> next(g)
16
>>> next(g)
36
>>> next(g)
64
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
当然我们可以使用 for 循环来输出,不用这么麻烦
>>> for n in g:
... print(n)
0
4
16
36
64
在函数中使用 yield 关键词,创建generator函数,比如斐波拉契数列:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n += 1
return 'done'
值得注意的是python的这种赋值的语法,十分的简洁:
n, a, b = 0, 0, 1
# 还有
a, b = b, a + b
# 相当于
a = b
b = a + b
调用函数生成一个generator对象:
>>> g = fib(6)
>>> g
<generator object fib at 0x104feaaa0>
使用 for 循环来输出
>>> for n in g:
... print(n)
1
1
2
3
5
8
这样一来就得不到return语句后面的值了(即'done'),如果想要拿到返回值,则必须捕获StopIteration异常,返回值包含在StopIteration的value中:
>>> g = fib(6)
>>> while True:
... try:
... x = next(g)
... print('g:', x)
... except StopIteration as e:
... print('Generator return value', e.value)
... break
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done
五.Iterable 和 Iterator
可迭代和迭代器是2个不同的概念,其中:
- 集合类型的,如 list, dict, str, 都是Iterable的,但不是Iterator, 凡是可作用于for循环的对象都是Iterable
- 像generator对象可使用 next() 函数的都是 Iterator的,同时也是可迭代的Iterable
比如:
from collections import Iterable
# list
>>> isinstance([], Iterable)
True
# dict
>>> isinstance({}, Iterable)
True
# str
>>> isinstance('abc', Iterable)
True
# tuple
>>> isinstance((1, 2, 3), Iterable)
True
# generator
>>> isinstance((x for x in range(10)), Iterable)
True
# 数值
>>> isinstance(100, Iterable)
False
判断一个对象是否是 Iterator
from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
可以使用 iter()
将 list, dict, str 等Iterable变为 Iterator
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
python中将Iterator对象表示为一个数据流,Iterator对象可以被next()函数调用并不断的返回下一个数据,直到没有数据抛出 StopIteration 错误, Iterator的计算是 惰性的, 可以表示一个无限大的数据流
总结
本章主要将的是一些常用的数据操作:
- 切片,和js中的slice类似,只是写法不同,还有就是可以隔几个选取1个,稍微有点差异
- 迭代,对集合类型的数据进行for...in循环, 字典中存在 'values()', 'items()' 等方法, list如果想使用索引,可以使用内置的 enumerate() 函数
- 列表生成式,快速生成一个list的简便写法,可以写二维或以上的for循环,还可以添加条件判断
- 生成器,这个用来对函数进行控制,快速生成生成器对象的方式和列表生成式比较类似
- 可迭代和迭代器的区别,以及使用 iter() 将可迭代转换为迭代器
- 异常捕获使用 try...except ExceptType
- 另外接触到的函数 lower(), upper(), title()
2017年3月5日 21:55:26