06 python中的高级特性 - lovemoganna/DataStructure GitHub Wiki
# 输出1,3,5,7,...99
L=[]
n= 1
while n<= 100:
L.append(n)
n = n +2
print(L)
# 代码越少,开发效率越高.
# 下面这行代码就可以代替啦:
[x for x in range(1,100)]
File "<ipython-input-219-f1ea90287ed7>", line 11
[x for x in range(1,100)\n]
^
SyntaxError: unexpected character after line continuation character
L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
# 取前面3个元素
[L[0],L[1],L[2]]
# 切面的表达
L[0:3]
L[:3] # 索引如果是0 开始,可以省略掉.
L[-1:] # 倒着只能取1个元素
# 千万记住倒数第一个元素的索引是-1,正着数第一个元素的索引是0.
['Jack']
# 循环的方式表达,取出3个元素.
r =[]
n =3
for i in range(n):
r.append(L[i])
print(r)
['Michael', 'Sarah', 'Tracy']
# 创建一个0-99的数列
L = list(range(100))
L[:10] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
L[-10:] # [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
L[10:20]
L[:10:3] # [0, 3, 6, 9] 前10个数,每3个取一个.
L[::5] # 所有数,每5个取一个
L[:] # 复制一个list
(0,1,2,3,4,5)[:3] # 取Tuple中的前3个数.还是一个Tuple
'ABCDEFG'[:2] # 取出前2个字符
# 截取字符串
'ABCDEFG'[::2] # 取出间隔为2的所有字符,从A开始算,也就是'ACEG'
'ABCDEFG'[1:] # 除去第一个字符串的所有部分
'ABCDEFG'[-1:]# 除去最后一个字符串的所有部分
'BCDEFG'
def trim(s):
# 字符串的前面是空格
while s[:1] == ' ':
s = s[1:]
# 字符串的后面是空格
while s[-1:] == ' ':
s = s[:-1]
return s
trim(' hello ')
'hello'
# c 语言中的list的遍历
for(i =0;i<list.length;i++){
n=list[i];
}
# python 主要是通过 for ... in 来进行迭代的,比较抽象
# 下面迭代一个dict
ds={'a':'1','c':'2','d':'3'}
for d in ds:
# 打印dict中的key和value
print('key=',d,'value=',ds.get(d))
# dict的存储不是按照list的方式顺序排列,所以迭代出的结果顺序很可能不一样.
# 下面迭代出所有的value
for value in ds.values():
print(value)
# 下面迭代出所有的key和value
for k, v in ds.items():
print(k+":"+v)
# 字符串也能迭代
for ch in 'ABC':
print(ch)
key= a value= 1
key= c value= 2
key= d value= 3
1
2
3
a:1
c:2
d:3
A
B
C
# python是如何判断对象是否可进行迭代的哪?
from collections import Iterable
isinstance('abc',Iterable) # True 代表字符串可以迭代.
isinstance((1,2,3),Iterable) # list也可以迭代
isinstance({'a':'1','b':'2','c':'3'},Iterable) # dict也可以迭代
True
# 对list实现类似Java那样的下标循环
# Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:
for i , value in enumerate(['a','b','c']):
print(i,value)
print()
# for循环里,同时引用了两个变量的情况
for x,y in [(1,2),(2,3),(3,4)]:
print(x,y)
0 a
1 b
2 c
1 2
2 3
3 4
# 发现最大值和最小值
def findMinAndMax(L):
# 判断list为0的情况
if len(L) == 0:
return(None, None)
else:
max = L[0]
min = L[0]
# list不为0 的情况
for s in L:
if s > max:
max = s
if s < min:
min = s
return(min, max)
findMinAndMax([0,1,2,3,4,5,6,6])
(0, 0)
def findMinAndMax(L):
if len(L) == 0:
return (None, None)
else:
s_max = max(L)
s_min = min(L)
return (s_min, s_max)
findMinAndMax([0,1,2,3,4,5,6,6])
(0, 6)
def findMaxAndMin(L):
if len(L)==0:
return None
else:
s_max=max(L)
s_min=min(L)
return (s_min,s_max)
findMaxAndMin([0])
(0, 0)
# list(range(1, 11))
# 1-10的自乘
L=[]
for x in range(1,11):
L.append(x*x)
L
[x * x for x in range(1, 11)] # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[x * x for x in range(1, 11)if x% 2 == 0]# 加上条件判断的写法
[m + n for m in 'ABC' for n in'XYZ'] # 双层循环:['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
import os # 导入os模块.
[d for d in os.listdir('.')] # # os.listdir可以列出文件和目录
['.ipynb_checkpoints',
'04-settest.ipynb',
'05-函数.ipynb',
'beautifulsoup.ipynb',
'cookie.txt',
'notebook.tex',
'python06-高级特性.ipynb',
'regex.ipynb',
'requests.ipynb',
'Untitled.ipynb',
'urllib.ipynb',
'基本语法.ipynb',
'集合和数组.ipynb']
d={'x':'1','y':'2'}
for k,v in d.items():
print(k,v)
# 列表生成式的表述
[k + '=' + v for k, v in d.items()]
L=['Hello','World','IBM','Apple']
[s.lower() for s in L] # 将所有字符串小写
# 只有字符串才能使用lower()方法
L = ['Hello', 'World', 18, 'Apple', None]
# [s.lower() for s in L] # 'int' object has no attribute 'lower'
# 使用内建的isinstance函数可以判断一个变量是不是字符串
x = 'abc'
y=123
isinstance(x,str) # True
isinstance(y,str) # False
x 1
y 2
False
# 在python里面,一边循环一边计算的机制,称为生成器:generator
L = [x*x for x in range(10)]
L # L是一个list
g=(x * x for x in range(10))
g # g 是一个生成器
# 如果要一个一个打印出来,可以通过next()函数来获得generator的下一个返回值
next(g) # 0
next(g) # 1
# ...依次类推
# generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,
# 没有更多的元素时,抛出StopIteration的错误。
#更加方便的调用方法是for循环,因为generator也是一个可迭代对象
g = (x * x for x in range(10))
for i in g:
print(i)
0
1
4
9
16
25
36
49
64
81
著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到: 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
# 菲波那切数列
def fib(max):
n, a, b = 0, 0, 1
while n < max:
# print(b)
yield b
a, b = b, a + b
n = n + 1
return 'done'
f=fib(6)
f
# 此时我们可以通过循环来取得generator里面的值,而不必通过next()
for i in f:
print(i)
# 但是此时我们发现拿不到return 里面的值.其实就是一个捕获异常的表达
g = fib(6)
# 加上这个就相当于不断的去判断是否符合条件.
while True:
try:
x= next(g)
print('g',x)
except StopIteration as e:
print('Generator return value:',e.value)
break
#<generator object fib at 0x0000000004DFB990>
# 此时想要把fib函数变为generator.只需要将b,改为 yield b就可以了
# 如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:
1
1
2
3
5
8
g 1
g 1
g 2
g 3
g 5
g 8
Generator return value: done
t = (b,a+b) # t 是一个Tuple
a = t[0]
b = t[1]
# 就相当于 t = (t(1),t(0) + t(1))
a,b=(1,2)
print(a)
print(b)
# fib函数可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。
generator和函数执行的流程:
1.函数是顺序执行,遇到return语句或者最后一行函数语句就返回,
2.变成generator的函数,在每次调用next()函数的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句执行.
def odd():
print('step1')
yield 1
print('step2')
yield (3)
print('step3')
yield(5)
o = odd()# 调用的时候,先要生成一个generator的对象,然后用next()不断获得下一个返回值.
next(o) # step1 1
next(o) # step2 3
next(o) # step3 5
next(o) # StopIteration:
# 因为加了yield关键字,所以odd函数已经变为了generator,在执行的过程中,遇到yield就会中断,下次可以再次在中断的位置执行.
# 执行了3次next()后,没有yield可以执行了.
step1
step2
step3
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-179-03039e004379> in <module>()
11 next(o)
12 next(o)
---> 13 next(o)
StopIteration:
直接做for循环的数据类型:
1.集合数据类型:list,tuple,dict,set,str
2.generator类型:包括生成器和带yield的generator function
这些直接作用for循环的对象统称为可迭代对象,统一称为Iterable.
可以使用isinstance()判断一个对象是否是Iterable对象
from collections import Iterable,Iterator
isinstance([],Iterable)
isinstance({},Iterable)
isinstance('abc',Iterable)
isinstance((x for x in range(10)),Iterable)
#isinstance(100,Iterable) # False,可变对象.
isinstance(iter([]), Iterator)
isinstance(iter({}), Iterator)
isinstance(iter('abc'), Iterator)
True
此时需要记住:
1.生成器都是Iterator对象. list,dict,str是Iterable,但不是Iterator.
2.将list,dict,str等Iterable变成Iterator可以使用iter()函数.
python中的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据.直到没有抛出StopIteration错误.
可以把这个数据流看做是一个有序序列.但我们不能提前知道序列的长度,只能不断的通过next()函数实现按需计算下一个数据.
所以Iterator的计算是惰性的,只有在需要返回下一个数据的时候他才会计算.
Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
Python的for循环本质上就是通过不断调用next()函数实现的,
[x for x in range(1,11)]
L=(x for x in range(1,11))# 这就相当于一个generator,生成器.
next(L)
next(L)
# for循环的表示
for x in [1,2,3,4,5]:
print(x)
# 等价于下面的next()函数的不断调用
# 先获得Iterator对象
it=iter([1,2,3,4,5])
# 循环
while True:
try:
#获得下一个值
next(it)
except StopIteration:
#遇到StopIteration就退出循环
break
# 复习一下带yield参数的生成器
def oh(a):
if a >= 18:
yield('你成年了,可以随便狼了!')
else:
yield('你未成年,没有足够的自由!')
next(oh(80))
next(oh(12))
1
2
3
4
5
'你未成年,没有足够的自由!'