Study 6 —— 高级特性

资料地址: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循环。

时间: 2024-10-12 07:37:09

Study 6 —— 高级特性的相关文章

Zookeeper系列五:Master选举、ZK高级特性:基本模型

一.Master选举 1. master选举原理: 有多个master,每次只能有一个master负责主要的工作,其他的master作为备份,同时对负责工作的master进行监听,一旦负责工作的master挂掉了,其他的master就会收到监听的事件,从而去挣脱负责工作的权利,其他没有争夺到负责主要工作的master转而去监听负责工作的新master. 本质其实是利用zookeeper的临时节点的特性:临时节点随着会话的消亡二消亡,同一个临时节点只能创建一个,创建失败的节点(从master)对创

MapReduce编程实战之“高级特性”

本篇介绍MapReduce的一些高级特性,如计数器.数据集的排序和连接.计数器是一种收集作业统计信息的有效手段,排序是MapReduce的核心技术,MapReduce也能够执行大型数据集间的""连接(join)操作. 计数器 计数器是一种收集作业统计信息的有效手段,用于质量控制或应用级统计.计数器还可用于辅助诊断系统故障.对于大型分布式系统来说,获取计数器比分析日志文件容易的多. 示例一:气温缺失及不规则数据计数器 import java.io.IOException; import

javascript高级特性

01_javascript相关内容02_函数_Arguments对象03_函数_变量的作用域04_函数_特殊函数05_闭包_作用域链&闭包06_闭包_循环中的闭包07_对象_定义普通对象08_对象_定义函数对象09_对象_内建对象10_原型_为函数对象增加属性或方法11_原型_利用函数对象本身重写原型12_继承_函数对象之间的继承13_继承_普通对象之间的继承 javascript高级特性(面向对象): * 面向对象:   * 面向对象和面向过程的区别:     * 面向对象:人就是对象,年龄\

python之高级特性

掌握了Python的数据类型.语句和函数,基本上就可以编写出很多有用的程序了. 比如构造一个1, 3, 5, 7, ..., 99的列表,可以通过循环实现: L = [] n = 1 while n <= 99: L.append(n) n = n + 2 取list的前一半的元素,也可以通过循环实现. 但是在Python中,代码不是越多越好,而是越少越好.代码不是越复杂越好,而是越简单越好. 基于这一思想,我们来介绍Python中非常有用的高级特性,1行代码能实现的功能,决不写5行代码.请始终

Python_高级特性

Python高级特性 author:lxy 切片.迭代.列表生成式.生成器 切片 Python中 代码越少越简单越好, 我们要取一个list中的某一部分的元素的我们可以使用判断+循环实现,在Python提供了专门的方法--切片 slice切片,用来获取list中某一段元素 tuple.str等都看做是一种list只是使用切片获取的片段还是他们原来相应的类型 例1.对list进行切片 >>> n = [1,3,2,5,6,8] >>> n[0:3]           

JSP简明教程(五):高级特性

JSP过滤器 过滤器的作用是给web请求增加额外的逻辑,每个页面可以被多个过滤器进行处理.过滤器需要在web.xml文件中进行定义,语法如下.过滤器的执行顺序与filter-mapping的定义顺序相同. <filter> <filter-name>FilterName</filter-name> <filter-class>TestFilter</filter-name> <init-param> <param-name>

Day-5: Python高级特性

python的理念是:简单.优雅.所以,在Python中集成了许多经常要使用的高级特性,以此来简化代码. 切片: 对于一个list或者tuple,取其中一段的元素,称为切片(Slice). L[start:end]表示取L中从索引号为start到end的元素,其中如果顺着取,则索引号范围为0~len(L)-1:反着取,则索引号范围为-1~-len(L). 迭代: Python中迭代用for...in来完成.对于list或者tuple,就是for name in names之类:而对于dict,就

ActiveMQ中的Destination高级特性(一)

---------------------------------------------------------------------------------------- Destination高级特性----->Composite Destinations 组合队列Composite Destinations : 允许用一个虚拟的destination代表多个destinations,这样就可以通过composite destinations在一个操作中同时向多个queue/topic发

《深入理解Java虚拟机 JVM高级特性...》核心笔记

深入理解Java虚拟机 JVM高级特性与最佳实践(第二版) 核心笔记 JAVA 环境: JAVA虚拟机高级特性: 一:java内存区域与内存异常 一):运行数据区     1:程序计数器(Program Counter Register),也称"PC寄存器" A:用来指示需要执行哪条指令的.(在汇编语言中,CPU在得到指令之后,程序计数器便自动加1或者根据                    转移指针得到下一条指令的地址,如此循环,直至执行完所有的指令.) B:由于在JVM中,多线程