跳至主要內容

高级特性

yczha大约 5 分钟python基础python语法python

Python基础系列内容为学习廖雪峰老师Python3教程的记录,廖雪峰老师官网地址:廖雪峰Python3教程open in new window

切片

为了简化Python中数据集合的取用,Python使用slice(切片)操作,我们来考察这样一个操作:对list去取出所有元素:

L=[1,2,3,4,5,6,7,8,9,10]

常规的解决思路是遍历:

>>> L=[1,2,3,4,5,6,7,8,9,10]
>>> newL=[]
>>> for i in range(len(L)):
...     newL.append(L[i])
...
>>> newL
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

当使用切片操作后,可以这样完成:

>>> L[:]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

切片语法规则:指定起始位置和终止位置,起始从0开始,比如,取前五个元素:

>>> L[0:5]
[1, 2, 3, 4, 5]

若从零位置开始,也可以省略开始0,若到尾结束,则可以省略尾位置

>>> L[:5]
[1, 2, 3, 4, 5]
>>> L[5:]
[6, 7, 8, 9, 10]

可以指定数据间隔,比如访问奇数项:

>>> L[0:10:2]
[1, 3, 5, 7, 9]

可以倒序访问:

>>> L[-10:-1]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

切片操作对tuple同样适用:

>>> T=(1,2,3,4,5,6,7,8,9,10)
>>> T[:]
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
>>> T[0:10:3]
(1, 4, 7, 10)
>>> T[-5:-1]
(6, 7, 8, 9)

迭代

任何可迭代对象都可以使用for循环进行迭代,比如:

>>> d={'Mark':18,'Bob':19,'Alex':17,'Lucy':21,'Nancy':22}
>>> for key in d:
...     print(key)
...
Mark
Bob
Alex
Lucy
Nancy

也可以访问value:

>>> for value in d.values():
...     print(value)
...
18
19
17
21
22

循环也支持多个值,比如:

>>> for key,value in d.items():
...     print(key,':',value)
...
Mark : 18
Bob : 19
Alex : 17
Lucy : 21
Nancy : 22

实现按照下标进行循环:enumerate()函数

>>> L=[1,2,3,4,5,6,7,8,9,10]

>>> for i in enumerate(L):
...     print(i)
...
(0, 1)
(1, 2)
(2, 3)
(3, 4)
(4, 5)
(5, 6)
(6, 7)
(7, 8)
(8, 9)
(9, 10)

判断可迭代性:isinstance()函数Iterable参数:

>>> from collections import Iterable
>>> isinstance([1,2,3,4,5],Iterable)
True
>>> isinstance((1,3,4,5),Iterable)
True
>>> isinstance({'Mark':22,'Lucy':12},Iterable)
True
>>> isinstance('qweertyui',Iterable)
True
>>> isinstance(121212,Iterable)
False

从上边看到:list,tuple,dict,string等对象都是可迭代的,但数字不行。

列表生成式

列表生成式,用来简化创建List。

创建L[1,2,3,4,5,6,7,8,9,10]

>>> list(range(1,11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

创建L[1*1,2*2,3*3,4*4...,10*10]

>>> [x*x for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

删选出上面list中的奇数项

>>> [x*x for x in range(1,11) if x%2!=0]
[1, 9, 25, 49, 81]

可以用双重循环生成全排列

>>> [m+n for m in 'ABCD'for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ', 'DX', 'DY', 'DZ']

实例:列出当前目录下的所有文件名称

C:\Users\fanyu\Desktop\PYTHON>python
Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> [d for d in os.listdir('.')]
['Add_end.py', 'cal.py', 'enroll.py', 'fact.py', 'FirstPythonProgramm.py', 'getResult.py', 'Hanoi.py', 'my_abs.py', 'python-3.6.1-amd64.exe', 'recursive.py', 'Variable.py', '__pycache__']

用两个变量生成list

>>> d={'A':'a','B':'b','C':'c'}
>>> [k+'='+v for k,v in d.items()]
['A=a', 'B=b', 'C=c']

实例:大写字母转为小写

>>> L=['Bob','Hello','Welcome YOU']
>>> [s.lower() for s in L]
['bob', 'hello', 'welcome you']

生成器

对于有着递推关系的数据集合,可以使用生成器来存储,从而节省空间。

示例:L[1,4,9,16,25,36,49,64,81,100]

对于这样一个list,有着明显的递推关系:ln=n2,这样的关系可以用生成器来表示,示例如下:

>>> g=(x*x for x in range(1,11))
>>> g
<generator object <genexpr> at 0x000002A067593A98>
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
>>> next(g)
25
>>> next(g)
36
>>> next(g)
49
>>> next(g)
64
>>> next(g)
81
>>> next(g)
100

从上面的示例可以看出:list的生成器使用仅需把[]改为()即可。访问生成器则使用next()函数,当然也可以使用for x in xx 循环:

>>> g=(x*x for x in range(1,11))
>>> g
<generator object <genexpr> at 0x000002A067593AF0>
>>> for n in g:
...     print(n)
...
1
4
9
16
25
36
49
64
81
100

生成器也可以在函数中实现,此时需使用关键字yield

来看一个例子:杨辉三角open in new window

        1
      1   1
    1   2   1     
  1   3   3   1
1   4   6   4   1

下面实现它的生成器的函数

def YHtriangle(n):
  L=[1]
    i=1
    while i<=n:
        yield L
        L=[1]+[L[x]+L[x+1] for x in range(len(L)-1)]+[1]
        i=i+1

调用上面的函数

>>> tri=YHtriangle(5)
>>> next(tri)
[1]
>>> next(tri)
[1, 1]
>>> next(tri)
[1, 2, 1]
>>> next(tri)
[1, 3, 3, 1]
>>> next(tri)
[1, 4, 6, 4, 1]
>>> next(tri)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

迭代器

可以被next()函数调用不断返回下一个值的对象称为迭代器Iterator。注意区别前面所提到的Iterable,到此处,我们可以做个对比测试:

#Iterator
>>> from collections import Iterator
>>> isinstance([],Iterator)
False
>>> isinstance((),Iterator)
False
>>> isinstance({},Iterator)
False
>>> isinstance('',Iterator)
False

#Iterable
>>> from collections import Iterable
>>> isinstance([],Iterable)
True
>>> isinstance((),Iterable)
True
>>> isinstance({},Iterable)
True
>>> isinstance('',Iterable)
True

可见:list,tuple,dict,set,str几种数据类型都是可迭代的(Iterable),但却都不是Iterator

小结

我们做如下小结:

  • 凡是可作用于for循环的对象都是Iterable类型
  • 凡是可以作用于next()函数的对象都是Iterator类型
  • 集合数据类型(list,tuple,dict,set,str)等都属于Iterable类型但都不属于Iterator类型。