码迷,mamicode.com
首页 > 其他好文 > 详细

Study 6 —— 高级特性

时间:2017-08-29 21:47:07      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:n个元素   可迭代对象   one   迭代   lan   return   对象   dict   ansi   

资料地址:https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868196169906eb9ca5864384546bf3405ae6a172b3e000

构造一个1, 3, 5, 7, ..., 99的列表,可以通过循环实现:

L = []
n = 1
while n <= 99:
    L.append(n)
    n = n + 2

切片

取一个list或tuple的部分元素是非常常见的操作。

>>> L = [‘Michael‘, ‘Sarah‘, ‘Tracy‘, ‘Bob‘, ‘Jack‘]

#取前3个元素
>>> [L[0], L[1], L[2]]
[‘Michael‘, ‘Sarah‘, ‘Tracy‘]

#取前N个元素,也就是索引为0-(N-1)的元素,可以用循环:
>>> r = []
>>> n = 3
>>> for i in range(n):
...     r.append(L[i])
... 
>>> r
[‘Michael‘, ‘Sarah‘, ‘Tracy‘]

对这种经常取指定索引范围的操作,用循环十分繁琐,因此,Python提供了切片(Slice)操作符,能大大简化这种操作。

对应上面的问题,取前3个元素,用一行代码就可以完成切片:

>>> L[0:3]
[‘Michael‘, ‘Sarah‘, ‘Tracy‘]

L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素。索引0可以省略。

>>> L[-2:]
[‘Bob‘, ‘Jack‘]
>>> L[-2:-1]
[‘Bob‘]

 

>>> L = range(100)           #创建一个0-99的数列
>>> L
[0, 1, 2, 3, ... ,98, 99]
>>> L[:10]                         #取前10个数
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> L[-10:]                        #取后10个数
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
>>> L[10:20]                     #取第11-20个数
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> L[:10:2]                     #在前10个数中每2个取一个
[0, 2, 4, 6, 8]
>>> L[::5]                         #在所以数里每5个取一个
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
>>> L[:]                            #显示整个数列
[0, 1, 2, 3, ... ,98, 99] 

tuple和字符串切片:

>>> (0, 1, 2, 3, 4, 5)[:3]
(0, 1, 2)
>>> ‘ABCDEFG‘[:3]
‘ABC‘
>>> ‘ABCDEFG‘[::3]
‘ADG‘

迭代

当我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行。

如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:

>>> from collections import Iterable
>>> isinstance(‘abc‘, Iterable) 
True
>>> isinstance([1, 2, 3], Iterable)     
True
>>> isinstance(123, Iterable)         
False

dict迭代:

>>> d = {‘a‘: 1, ‘b‘: 2, ‘c‘: 3}        #dict迭代是key
>>> for key in d:
...     print key
... 
a
c
b
>>> for value in d.itervalues():     #value迭代
...     print value
... 
1
3
2
>>> for k, v in d.iteritems():          #key和value同时迭代
...     print k, v
... 
a 1
c 3
b 2    

Python内置的enumerate函数可以把一个list变成索引-元素对,这样在for循环中可以同时迭代索引和元素本身:

>>> for i, value in enumerate([‘A‘, ‘B‘, ‘C‘]):
...     print i, value
... 
0 A
1 B
2 C

#for循环中的两个变量使用
>>> for x, y in [(1, 1), (2, 4), (3, 9)]:
...     print x, y
... 
1 1
2 4
3 9

任何可迭代对象都可以作用于for循环,包括我们自定义的数据类型,只要符合迭代条件,就可以使用for循环。

列表生成式

列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用range(1, 11)

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

生成[1*1, 2*2, 3*3, ... , 10*10]:

方法一:for循环

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

方法二:列表生成式

>>> [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]   
[4, 16, 36, 64, 100]

#两层循环
>>> [m + n for m in ‘ABC‘ for n in ‘XYZ‘]       
[‘AX‘, ‘AY‘, ‘AZ‘, ‘BX‘, ‘BY‘, ‘BZ‘, ‘CX‘, ‘CY‘, ‘CZ‘]

列出当前目录下的所有文件和目录名:

>>> import os            # 导入os模块
>>> [d for d in os.listdir(‘.‘)]          #os.listdir可以列出文件和目录    
[‘.cshrc‘, ‘test.py‘, ‘.pki‘, ‘.viminfo‘, ‘.npm‘, ‘.bash_history‘, ‘.bash_logout‘, ‘.cache‘, ‘test.html‘, ‘.bashrc‘, ‘install.log‘, ‘.bash_profile‘, ‘.ssh‘, ‘.tcshrc‘, ‘anaconda-ks.cfg‘, ‘tmp‘, ‘install.log.syslog‘, ‘tomcat_install.sh‘, ‘.ansible‘]

for循环其实可以同时使用两个甚至多个变量,比如dictiteritems()可以同时迭代key和value:

>>> d = {‘x‘: ‘A‘, ‘y‘: ‘B‘, ‘z‘: ‘C‘}
>>> for k, v in d.iteritems():
...     print k, ‘=‘, v
... 
y = B
x = A
z = C

列表生成式同样可以做到:

>>> d = {‘x‘: ‘A‘, ‘y‘: ‘B‘, ‘z‘: ‘C‘}
>>> [k + ‘=‘ + v for k, v in d.iteritems()]
[‘y=B‘, ‘x=A‘, ‘z=C‘]

改变字符串大小写:

>>> L = [‘Hello‘, ‘world‘, ‘IBM‘, ‘Apple‘]
>>> [s.lower() for s in L]
[‘hello‘, ‘world‘, ‘ibm‘, ‘apple‘]

isinstance函数可以判断一个变量是不是字符串:

>>> x = ‘abc‘
>>> y = 123
>>> isinstance(x, str)
True
>>> isinstance(y, str) 
False
>>> isinstance(y, int)
True

通过添加if语句保证列表生成式能正确地执行:

>>> L = [‘Michael‘, ‘Jim‘, 13, ‘Bob‘, ‘Hello World‘, None]
>>> [s.lower() if isinstance(s, str) else s for s in L]       
[‘michael‘, ‘jim‘, 13, ‘bob‘, ‘hello world‘, None]

生成器

在Python中,一边循环一边计算的机制,称为生成器(Generator)。

方法: 

第一种:把一个列表生成式的[]改成(),就创建了一个generator:

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x7fa74c03b5a0>
>>> g.next()      #逐个打印内部每个元素
0
>>> g.next()
1
>>> g.next()
4
>>> g.next()
9
>>> g = (x * x for x in range(10))    #for循环调用(generator是可迭代对象)
>>> for n in g:                   
...     print n                   
... 
0
1
4
9
16
25
36
49
64
81

第二种:如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

复杂的裴波拉契数列(Fibonacci)(除第一个和第二个数外,任意一个数都可由前两个数相加得到):

>>> def fib(max):            #列表生成式无法写出裴波拉契数列,可以定义函数打印出来    
...     n, a, b = 0, 0, 1
...     while n < max:
...         print b
...         a, b = b, a + b
...         n = n + 1
... 
>>> fib(6)       #打印前6位数字
1
1
2
3
5
8 

fib函数定义了斐波拉契数列的推算规则,从第一个元素开始推算出后续任意的元素,这种逻辑其实非常类似generator。

要把fib函数变成generator,只需要把print b改为yield b就可以了:

>>> def fib(max):
...     n, a, b = 0, 0, 1
...     while n < max:
...         yield b
...         a, b = b, a + b
...         n = n + 1
... 
>>> fib(6)
<generator object fib at 0x104feaaa0>

但是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

在上述例子中,我们在循环过程中不断调用yield,就会不断中断。

把函数改成generator后,我们基本上从来不会用next()来调用它,而是直接使用for循环来迭代:

>>> for n in fib(7):
...     print n 
... 
1
1
2
3
5
8
13

generator的工作原理:它是在for循环的过程中不断计算出下一个元素,并在适当的条件结束for循环。

Study 6 —— 高级特性

标签:n个元素   可迭代对象   one   迭代   lan   return   对象   dict   ansi   

原文地址:http://www.cnblogs.com/vurtne-lu/p/7450056.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!