2.条件、循环、迭代和列表解析

 

 

 

 

 

 

 六、流程控制和循环

 

if语句 

它由三部分组成: 关键字本身, 用于判断结果真假的条件表达式, 以及当表达式为真或者非零时执行的代码块

 

可支持else和elif;条件表达式并不需要用括号括起来

1、标准if 条件语句的语法如下:

if expression:

    expr_true_suite

 

如果表达式的值非0 或者为布尔值True, 则代码组if_suite被执行; 否则就去执行下一条语句。

 if 语句的 expr_true_suite 代码块只有在条件表达式的结果的布尔值为真时才执行, 否则将继续执行紧跟在该代码块后面的语句
单个 if 语句可以通过使用布尔操作符 and , or 和 not实现多重判断条件或是否定判断条件

 

else语句

1.和其他语言一样, Python 提供了与 if 语句搭配使用的 else 语句.

2.如果 if 语句的条件表达式的结果布尔值为假, 那么程序将执行 else 语句后的代码.

  语法如下:

if expression:
  expr_true_suite
else:
  expr_false_suite

3. 单个if语句可以通过使用布尔操作符and,or和not实现多重判断条件或是否定判断条件

4. 为了实现更好的可读性,可以使用()分组,但是python并不强制这么做

 

 

例子1:编写 login.py2 脚本,实现以下目标

1、提示用户输入用户名和密码

2、用户名和密码分别保存在变量中
 3、如果用户名为 bob 并且密码为 123456,则输出 Login successful,否则输出 Login inorrect

 

#!/usr/bin/env python
username = raw_input('username: ')
password = raw_input('password: ')
if username == 'bob' and password == '123456':
    print 'Login successful'
else:
    print 'Login incorrect'

 

  执行结果:

username: bob
password: 123456
Login successful

 

例子2:输入密码时,如果想要不可见,需要利用getpass 模块中的 getpass方法

 

#!/usr/bin/env python
#coding:utf-8
import getpass
username = raw_input('username: ')
password = getpass.getpass("password: ")  #使用getpass模块隐藏回显
if username == 'bob' and password == '123456':
    print 'Login successful'
else:
    print 'Login incorrect'

 

结果见下图,在输出名字后不再运行,无法继续输入密码

 

 

这是pycharm这个编译器的问题要想让程序继续运行且,在输入密码不展示输入的内容,需要在命令行运行当前和python文件,类似linux方法。
有两种方法
1、输入python xx.py
如下图:使用Terminal

 

2、在当前py文件上右键点击 show in explorer-->在文件夹地址栏中输入cmd打开windows命令界面-->输入python xx.py

 

 

 

 

 elif (即 else-if )语句

1.elif 是 Python 的 else-if 语句, 它检查多个表达式是否为真, 并在为真时执行特定代码块中的代码

2.和 else 一样, elif 声明是可选的, 然而不同的是, if 语句后最多只能有一个 else语句, 但可以有任意数量的 elif 语句

语法如下:

if expression1:
  expr1_true_suite
elif expression2:   expr2_true_suite
elif expressionN:   exprN_true_suite
else:   none_of_the_above_suite
 

 

 
 
例子1:编写 score.py 脚本,根据用户输入的成绩分档,要求如下:
1、如果成绩大分 60 分,输出“及格”
2、如果成绩大于 70 分,输出“良”
3、如果成绩大于 80 分,输出“好”
4、如果成绩大于 90 分,输出“优秀”
5、否则输出"不及格"
6、不在此范围,则输出"不在此范围,正确的范围应该是0-100"
 
#!/usr/bin/env python
#coding:utf-8


score = int(raw_input("score:"))
if score >100 or score <0:
    print "不在此范围,正确的范围应该是0-100"
else:
    if score >=90:
        print "优秀"
    elif score>=80:
        print ""
    elif score >=70:
        print ""
    elif score >=60:
        print "及格"
    else:
        print "不及格"

 



条件表达式或三元运算符

1、 python 在很长的一段时间里没有条件表达式(C ? X :Y),或称三元运算符,C为表示式
2、从Python 2.5集成的语法确定为: X if C else Y
3、如果条件成立则返回X,否则返回Y
 
>>> x, y = 3, 4
>>> smaller = x if x < y else y
>>> print smaller
3

 

 while 循环

1、当需要语句不断的重复执行时,可以使用while循环

语法如下:

while expression:

         while_suite

语句while_suite会被连续不断的循环执行,直到表达式的值变成0或False 才停止执行。

 通常在当循环次数不确定时使用while循环

这种类型的循环机制常常用在计数循环中

 

例子1:从1加到100,计算结果

流程图如下:

 

 代码如下:

#!/usr/bin/env python
#coding:utf-8
sum100 = 0
counter = 1

while counter <= 100:
    sum100 += counter
    counter += 1

print "result is %d" % sum100

执行结果:

result is 5050

 

2、 while语句也可以使用else语句,当循环结束的时候,会执行else语句

while else 循环和 while 循环不同的地方在于,如果是正常终止的循环(没有 break),最后一次循环完毕后,会接着执行 else 中的语句;

如果是在循环里面加上了 ifbreak 时,则只要满足 if 条件就会直接终止循环,不再执行任何语句;

 

#!/usr/bin/env python
#coding:utf-8
sum100 = 0
counter = 1

while counter <= 100:
    sum100 += counter
    counter += 1
else:
    print "result is %d" % sum100

执行结果

result is 5050

 

break语句

1.break语句可以结束当前循环然后跳转到下条语句
2.常用在当某个外部条件被触发(一般通过 if 语句检查), 需要立即从循环中退出时.
3.break 语句可以用在 while 和 for 循环中.
4.写程序的时候,应尽量避免重复的代码,在这种情况下可以使用while-break结构


while True:
  name = raw_input('username: ')
  if name == 'tom':
    break

print 'your name is %s' % name
 

 

continue语句

1.当遇到continue语句时,程序会终止当前循环,并忽略剩余的语句,然后回到循环的顶端

2、在开始下一次迭代前,如果是条件循环, 我们将验证条件表达式.

3、如果是迭代循环,我们将验证是否还有元素可以迭代. 只有在验证成功的情况下, 我们才会开始下一次迭代

 

例子1:计算1-100偶数之和

#!/usr/bin/env python
#-*- coding:utf-8 -*-

sum100 = 0
counter = 0

while counter <= 100:
    counter += 1
    if counter % 2:
        continue
    sum100 += counter
     
print sum100

 

执行结果:

2550

例子2:计算1-100所有奇数之和:

#!/usr/bin/env python
#-*- coding:utf-8 -*-
sum100 = 0
counter = 0

while counter < 100:
    counter += 1
    if not counter % 2:
        continue
    sum100 += counter

print sum100

执行结果:

2500

 

例子3:计算1-100所有奇数之和

#!/usr/bin/env python
#-*- coding:utf-8 -*-
sum100 = 0
counter = 0

while True:
    counter += 1
    if counter % 2 == 0:
        continue
    if counter >100:
        break

    sum100 += counter

print "result is %d" % sum100

 

执行结果:

result is 2500

 

例子4:计算1-100所有奇数之和

#!/usr/bin/env python
#-*- coding:utf-8 -*-
sum100 = 0
counter = 0

while counter < 100:
    counter += 1
    if not counter % 2:
        continue
    sum100 += counter

else:
    print sum100

执行结果:

2500

 

 3 有个需求,我想返回我的上层怎么做,用标识位!如下面的例子:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

count = 0
while True:
print "我是第一层"
jump_1_flag = False
while True:
print "我是第二层"
jump_2_flag = False
while True:
count += 1
print "我是第三层"
if count > 3:
jump_2_flag = True
break
if jump_2_flag:
print "第三层跳到我这里来了,我也要跳到第一层"
jump_1_flag = True
break

if jump_1_flag:
print "第二层和第三层跳到第一层了,我也要跳"
break

 执行结果:

我是第一层
我是第二层
我是第三层
我是第三层
我是第三层
我是第三层
第三层跳到我这里来了,我也要跳到第一层
第二层和第三层跳到第一层了,我也要跳

 

注意:在Python中,continue和break只能影响当前所在的这一层循环,如果是在内部循环中进行continue和break,那么外层循环不会受到影响

 

pass语句

1、Python 提供了 pass 语句, 它不做任何事情 - 即 NOP , ( No OPeration , 无操作)

 

 for循环

1、for循环:接受可迭代对象(例如序列或迭代器)作为其参数,每次迭代其中一个元素

2、for循环在Python中是一个通用的序列迭代器;

3、可以遍历任何有序的序列对象内的元素

4、它可以遍历序列成员, 可以用在 列表解析 和 生成器表达式中, 它会自动地调用迭代器的 next()方法, 捕获 StopIteration 异常并结束循环(所有这一切都是在内部发生的)

 

注意:序列包括字符串、元组和列表,但不限于这几种

 

一般语法

1.for 循环会访问一个可迭代对象(例如序列或是迭代器)中的所有元素, 并在所有条目都处理过后结束循环

 

 for iter_var in iterable:
  suite_to_repeat 

2、每次循环, iter_var 迭代变量被设置为可迭代对象(序列, 迭代器, 或者是其他支持迭代的对象)的当前元素, 提供给 suite_to_repeat 语句块使用

3、与while循环一样,支持break、continue、else语句

4、一般情况下,循环次数未知采用while循环,循环次数已知,采用for循环

 当满足循环条件时,则循环一直执行,不满足则退出;

 

 

用于序列类型

迭代序列有三种基本方法
1 通过序列项迭代

 
>> nameList = ['a', "Nicole", 'Steven', 'Henry']
>>> for eachName in nameList:
... print eachName, "Lim"
...
Walter Lim
Nicole Lim
Steven Lim
Henry Lim
 

2.通过序列索引迭代

 
>> nameList = ['Cathy', "Terry", 'Joe', 'Heather', 'Lucy']
>>> for nameIndex in range(len(nameList)):
... print "Liu,", nameList[nameIndex]
...
Liu, Cathy
Liu, Terry
Liu, Joe
Liu, Heather
Liu, Lucy
 

直接迭代序列要比通过索引迭代快

3 使用项和索引迭代
两全其美的办法是使用内建的 enumerate() 函数

 
>>> nameList = ['Donn', 'Shirley', 'Ben', 'Janice','David', 'Yen', 'Wendy']
>>> for i, eachLee in enumerate(nameList):
... print "%d %s Lee" % (i+1, eachLee)
...
1 Donn Lee
2 Shirley Lee
3 Ben Lee
4 Janice Lee
5 David Lee
6 Yen Lee
7 Wendy Lee
 

 

用于迭代器类型

1、用 for 循环访问迭代器和访问序列的方法差不多. 唯一的区别就是 for 语句会为你做一些额外的事情
2、迭代器并不代表循环条目的集合
3、迭代器对象有一个 next() 方法, 调用后返回下一个条目.

4、所有条目迭代完后, 迭代器引发一个 StopIteration 异常告诉程序循环结束. for 语句在内部调用 next() 并捕获异常.

 

 

range函数

1、Python 提供了两种不同的方法来调用 range() .

2、完整语法要求提供两个或三个整数参数: range(start, end, step =1)
3、range() 会返回一个包含所有 k 的列表, 这里 start <= k < end , 从 start 到 end , k 每次递增 step . step 不可以为零,否则将发生错误
4、如果只给定两个参数,而省略 step, step 就使用默认值 1 .

5、range() 还有两种简略的语法格式:range(end)和range(start, end)

 

6.for循环常与range函数一起使用
7.range函数提供循环条件


>>> range(5)               #列出数字0-4
[0, 1, 2, 3, 4]
>>> range(1, 5)
[1, 2, 3, 4]
>>> range(1, 5, 2)
[1, 3]
timer.py内容:

#!/usr/bin/env python
#coding:utf8

import time 

for i in range(1,11):
    print i,
    time.sleep(1)
    

 

 

xrange函数


1.xrange()类似range(),不过当你有一个很大的范围列表时,xrange()可能更为适合,因为它不会在内存里创建列表的完整拷贝
2.它只被用在for循环中,在for循环外使用它没有意义

3. 它的性能远高出range(),因为它不生成整个列表

#!/usr/bin/env python
# coding:utf8



for x in xrange(3):
    print x

 

 

与序列相关的内建函数

1、sorted() 和 zip() 返回一个序列(列表)
2、reversed() 和 enumerate() 返回迭代器(类似序列)

 

在shell中,测试175.40.2.0的IP是否ping得通,可以这样做:

ping.sh内容:

#!/bin/bash
for ip in 172.40.2.{1..254}:
do
    ping -c2 $ip &>/dev/null && echo "$ip: up" || echo "$ip:down"
done

而用Python也可以实现:

Linux:

#!/usr/bin/env python
#coding:utf8

import os 

for i in range(1,255):
    ip = "172.40.2.%s" % i 
    result = os.system("ping -c2 %s &>/dev/null" %ip)
    if result:
        print "%s:down " % ip 
    else:
        print "%s:up" % ip

 

Windows下:

#!/usr/bin/env python
#coding:utf8
import os
for i in range(1,255):
    ip = "192.168.9.%s" % i
    result = os.system("ping -n 1 %s > nul " %ip)
    if result:
        print "%s:down " % ip
    else:
        print "%s:up" % ip

 

注意:由于linux/unix下有/dev/null可以用于将输出安全丢弃,而Windows则有nul可以实现:形式只要为cmd ... >nul,标准输出的的内容就被丢弃.

 

 

 

9、计算斐波那契数列

斐波那契数列就是某一个数,总是前两个数之和,比如 0112358。由于输出是一串数字,可以用列表的结构存储。开始时,列表中有两个值,即 01

然后通过循环向列表中追加元素,追加元素总是列表中最后两个元素值之和。
当将脚本改成交互式运行时,需要注意,用户输入的数字,python 仍然将其视为字符而不是整型数字,需要使用 int()将用户输入做类型转换。

 

方法1:编写固定输出的斐波那契数列

#!/usr/bin/env python
#-*- coding:utf-8 -*-
fibs = [0, 1]    #定义一个列表

for i in range(8):  #循环8次
    fibs.append(fibs[-1] + fibs[-2])  #把最后一个和倒数第二个数字加起来,追加到列表里;这个类似fibs = fibs[-1] +fib[-2],你可以这样理解。

print fibs

执行结果:

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

 

方法2:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

fibs = [0, 1]

nums = int(raw_input('Input a number: '))

#因为已经定义nums的总个数了,所以迭代时需要nums -2
for i in range(nums - 2):
fibs.append(fibs[-1] + fibs[-2])
print fibs

 执行结果:

Input a number: 10
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

 

方法3:把下标和元素值打印出来

#!/usr/bin/env python
#-*- coding:utf-8 -*-

fibs = [0, 1]

for i in range(8):
fibs.append(fibs[-1] + fibs[-2])

#因为range会追加8次,即生成8个数字,再加上初始的2个总共10个数字
#所以长度为10,即len(fibs)为10
for i in range(len(fibs)): #把fibs的长度生成一个列表,即生成一组下标
print "index %d is %d" % (i, fibs[i]) #把下标和值打印出来

 

 

 执行结果:

index 0 is 0
index 1 is 1
index 2 is 1
index 3 is 2
index 4 is 3
index 5 is 5
index 6 is 8
index 7 is 13
index 8 is 21
index 9 is 34

 

方法4:通过使用enumerate把下标和元素值打印出来

 

#!/usr/bin/env python
#-*- coding:utf-8 -*-

fibs = [0, 1]

for i in range(8):
    fibs.append(fibs[-1] + fibs[-2])


for i, element in enumerate(fibs):    #enumerate作用于列表时,会产生两个值,一个是下标值,一个是下标对应的元素值
    print "index %d is %d" % (i, element)

执行结果:

index 0 is 0
index 1 is 1
index 2 is 1
index 3 is 2
index 4 is 3
index 5 is 5
index 6 is 8
index 7 is 13
index 8 is 21
index 9 is 34

 

其他语句

1、else语句
1. 与其他语言不同,python的while和for语句还支持else语句

2. 只有循环体正常结束时,else的代码块才会执行
3. 如果循环体内的代码被中断,那么else代码块也被中断,不会执行
 
2、break语句
1. break语句可以结束当前循环,然后跳转到循环以下语句
2. 可以用在while和for循环中
3. 一般通过if语句检查,当某个外部条件被触发立即从循环中退出

3、continue语句
1. 当遇到continue 语句时,程序会终止当前循环,并忽略剩余的语句,然后回到循环的顶端
2. 在开始下一次循环前,如果是条件循环,将验证条件表达式;如果是迭代循环,将验证是否还有元素可以迭代
3. 只有在验证成功后,才会开始下一次迭代或循环
 
4、pass语句
1. python没有使用传统的大括号来标记代码块,有时有些地方在语法上要求要有代码
2. python提供了pass语句,它不做任何事情

 

生成8位随机密码

方法1:

#!/usr/bin/env python
#coding:utf8

import random
import string

all_chs = string.letters + string.digits  #string.letters 表示大小写字母;string.digits表示数字

pwd = ''

for i in range(8):
    ch = random.choice(all_chs)  #choice() 方法返回一个列表,元组或字符串的随机项。
    pwd += ch
    
print pwd

 备注:

string模块部分内容:

   digits = '0123456789'
    hexdigits = '0123456789abcdefABCDEF'
    letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    lowercase = 'abcdefghijklmnopqrstuvwxyz'
    octdigits = '01234567'
    printable = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU...
    punctuation = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
    uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    whitespace = '\t\n\x0b\x0c\r '

这些内容通过string.__file__或者help(string)可以查看到

>>> import string
>>> string.__file__
'C:\\Python27\\lib\\string.pyc'
>>> 



 

random部分内容

 

 random.choice:从非空序列中选择一个随机元素。

 

方法2:

#!/usr/bin/env python
#coding:utf8

import random
import string

all_chs = string.letters + string.digits

pwd = ''

num = int(raw_input("number: "))


for i in range(num):
    ch = random.choice(all_chs)
    pwd += ch
    
print pwd

 

七、迭代

迭代器和iter()函数

1.为类序列对象提供了一个类序列的接口

2.从根本上说,迭代器就是有一个next()方法的对象
3.python的迭代无缝地支持序列对象,而且它还允许程序员迭代非序列类型
4.不能向后移动或回到开始,也不能复制一个迭代器

5.对一个对象调用iter()就可以得到它的迭代器
6.当迭代器条目全部取出后,会引发一个StopIteration异常,但这并不表示错误发生,只是告诉外部调用者迭代完成

 

>>> i = iter('py')
>>> i.next()
'p'
>>> i.next()
'y'
>>> i.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

 

文件迭代器

1.文件有一个__next__方法,每次调用时,就会返回文件的下一行。到达文件末尾时,__next__会引发内置的StopIteration异常

2.可迭代的"指的是支持iter的一个对象,而迭代器指的是iter所返回的一个支持next的对象

 

手动迭代:

1、为了支持手动迭代代码,Python 3.0还提供了一个内置函数next,它会自动调用一个对象的__next__方法

 

 

 

 为什么要迭代器

1.提供了可扩展的迭代器接口.
2.对列表迭代带来了性能上的增强.
3.在字典迭代中性能提升.
4.创建真正的迭代接口, 而不是原来的随机对象访问.
5.与所有已经存在的用户定义的类以及扩展的模拟序列和映射的对象向后兼容
6.迭代非序列集合(例如映射和文件)时, 可以创建更简洁可读的代码

 

如何迭代

1.根本上说, 迭代器就是有一个 next() 方法的对象, 而不是通过索引来计数
2.当你或是一个循环机制(例如 for 语句)需要下一个项时, 调用迭代器的 next() 方法就可以获得它.

3.条目全部取出后, 会引发一个 StopIteration 异常, 这并不表示错误发生, 只是告诉外部调用者, 迭代完成
4.迭代器也有一些限制. 例如你不能向后移动, 不能回到开始, 也不能复制一个迭代器
5.如果你要再次(或者是同时)迭代同个对象, 你只能去创建另一个迭代器对象
6.reversed() 内建函数将返回一个反序访问的迭代器
7.enumerate() 内建函数同样也返回迭代器
8.另外两个新的内建函数, any() 和 all() , 在 Python 2.5 中新增, 如果迭代器中某个/所有条目的值都为布尔真时,则它们返回值为真.

9.同时 Python 还提供了一整个 itertools 模块, 它包含各种有用的迭代器

 

可变对象和迭代器

1.一个序列的迭代器只是记录你当前到达第多少个元素, 所以如果你在迭代时改变了元素, 更新会立即反映到你所迭代的条目上.
2.在迭代字典的 key 时, 你绝对不能改变这个字典. 使用字典的 keys() 方法是可以的, 因为keys() 返回一个独立于字典的列表.

3.而迭代器是与实际对象绑定在一起的, 它将不会继续执行下去

 

 如何创建迭代器

1.对一个对象调用 iter() 就可以得到它的迭代器. 它的语法如下

iter(obj)
iter(func, sentinel )

2.如果你传递一个参数给 iter() , 它会检查你传递的是不是一个序列, 如果是, 那么很简单:根据索引从 0 一直迭代到序列结束.

3.另一个创建迭代器的方法是使用类, 一个实现了 __iter__() 和 next() 方法的类可以作为迭代器使用
4.如 果 是 传 递 两 个 参 数 给 iter() , 它 会 重 复 地 调 用 func , 直 到 迭 代 器 的 下 个 值 等 于sentinel

 

编写 testiter.py 脚本,练习各种迭代机制,主要要求如下

1、创建一个字符串,并通过 for 循环迭代各个字符
2、创建一个列表,并通过 for 循环迭代各个字符
3、打开一个文件,并通过 for 循环迭代各行
4、创建一个字典,并通过 for 循环迭代字典的键

 

方案:

很多 python 对象都支持与 for 一起迭代的功能。 利用这个功能可以方便的对对象进行遍历

 

#!/usr/bin/env python
#coding:utf-8

myStr = 'Hello world!'
myList = ["hello", "world"]
myFile = '/etc/hosts'
myDict = {"name": "bob", "age": 23}

for eachChar in myStr:
    print eachChar

for eachItem in myList:
    print eachItem

for eachLine in open(myFile):
    print eachLine, #注意逗号,用于抑制 print 打印的回车

for eachKey in myDict:
    print eachKey

执行结果:

[root@host-192-168-3-6 tarena]# python testiter.py 
H
e
l
l
o
 
w
o
r
l
d
!
hello
world
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
age
name

 

iter2.py内容:

#!/usr/bin/env python
#coding:utf8

astr = 'hello'
alist = ['tedu','cn']
adict = {'name':'bob','age':'20'}
aset = set(['new','world'])
fname = '/etc/hosts'
myiter = iter((10,20))

for ch in astr:print ch
for item in alist:print item 
for key in adict:print "%s:%s" % (key,adict[key])
for element in aset:print element
for i in myiter:print i

fobj = open(fname)
for line in fobj:
    print line,
fobj.close()

 

 执行结果:

[root@host-192-168-3-6 tarena]# python iter2.py 
h
e
l
l
o
tedu
cn
age:20
name:bob
new
world
10
20
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

 

 

八、列表解析

1、它是一个非常有用、简单、而且灵活的工具,可以用来动态地创建列表
2、语法: [expr for iter_var in iterable]
3、这个语句的核心是for循环,它迭代iterable对象的所有条目
4、expr应用于序列的每个成员,最后的结果值是该表达式产生的列表
5、可以在一行中使用一个for 循环将所有值放到一个列表当中:
6、迭代变量并不需要是表达式的一部分
7、列表解析的表达式可以取代内建的 map() 函数以及 lambda , 而且效率更高
8、结合 if语句,列表解析还提供了一个扩展版本的语法
 
[expr for iter_var in iterable if cond_expr] 

 

这个语法在迭代时会过滤/捕获满足条件表达式 cond_expr 的序列成员

 

列表解析式是将数据全部存储在内存中一并返回;

列表解析是Python迭代机制的一种应用,它常用于实现创建新的列表,因此用在[]中;

使用列表解析式,编译器会优化,不会因为简写而影响效率,反而优化提升效率,减少代码量,可读性强,工作量降低,减少出错;

 

 

例子1:快速的生成从1到4平方的列表
#i从1-4里取出数字,并将i取出的值进行2次幂运算
>>> a = [i  **  2  for  i  in  range(1, 5)]
>>> a
[1, 4, 9, 16]

例子2:快速的生成从1到10中奇数的平列表

#i从1-10里取出数字进行取模运算,如果取出的模为1,则把该值进行幂运算
>>> b = [i  **  2  for  i  in  range(1, 11)  if  i  %  2]
>>> b
[1, 9, 25, 49, 81]

例子3:快速的生成从1到10中偶数的平方的列表

#i从1-10里取出数字进行取模运算,如果取出的模为0,则把该值进行幂运算
>>> c = [i  **  2  for  i  in  range(1, 11)  if  not  (i  %  2)]
>>> c
[4, 16, 36, 64, 100]

 

 

 

lambda表达式

lambda原型为:lambda参数:操作(参数)

lambda函数也叫匿名函数,即没有具体名称的函数,他允许快速定义单行函数,可以用在任何需要函数的地方。

lambda会返回一个函数对象,但这个对象不会赋值给一个标识符

lambda表示式:后面,只能有一个表达式

像 if 或者 for 或者 print 等语句不能用于lambda中

lambda一般用来定义简单的函数

>>> map(lambda x: x ** 2, range(6))
[0, 1, 4, 9, 16]

 map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。

 

我们可以使用下面这样的列表解析来替换它:

>>> [x ** 2 for x in range(6)]
[0, 1, 4, 9, 16, 25]

 

 

使用 filter() 和 lambda 挑选出序列中的奇数:

>>> seq = [11, 10, 9, 9, 10, 10, 9, 8, 23, 9, 7, 18, 12, 11, 12]
>>> filter(lambda x: x % 2, seq)
[11, 9, 9, 9, 23, 9, 7, 11]

filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表

 

即使不用 filter() 和 lambda,我们同样可以使用列表解析来完成操作,获得想要的数字:

>>> [x for x in seq if x % 2]
[11, 9, 9, 9, 23, 9, 7, 11]

 

你需要迭代一个有三行五列的矩阵么? 很简单:

>>> [(x+1,y+1) for x in range(3) for y in range(5)]
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 1), (2, 2), (2,
3), (2, 4), (2, 5), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5)]

 


 

生成器表达式

1、生成器表达式是列表解析的一个扩展,它们的基本语法基本相同

2、生成器是特定的函数, 允许你返回一个值, 然后"暂停"代码的执行, 稍后恢复

3、列表解析的一个不足就是必要生成所有的数据, 用以创建整个列表. 这可能对有大量数据的迭代器有负面效应.

4、生成器表达式通过结合列表解析和生成器解决了这个问题.

5生成器表达式在 Python 2.4 被引入,它并不真正创建数字列表, 而是返回一个生成器
6、生成器在每次计算出一个条目后,把这个条目'产生'(yield)出来
7、生成器表达式使用了"延迟计算"(lazy evaluation), 所以它在使用内存上更有效
8、生成器表达式语法:(expr for iter_var in iterable if cond_expr)
9、生成器并不会让列表解析废弃, 它只是一个内存使用更友好的结构
 
 
 

集合解析式

 

集合解析式和列表解析式用法一样,只是集合解析式使用的是{}花括号; 

 

    set1 = {(x,x+1) for x in range(10)}
    print(set1)

 

字典解析式

 字典解析式也是使用{}花括号括起来的;

因为字典有key-value键值对,所以使用字典解析式时key会自动去重;

 

 

    # 字典解析式
    dict1 = {'{}'.format(x):x for x in range(10)}
    print(dict1)
    # 输出三个元素,因为会被key会被覆盖
    dict2 = {x:y for x in range(3) for y in range(3)}
    print(dict2)
    # 上式等价于
    dict3 = {}
    for x in range(3):
        for y in range(3):
            dict3[x] = y
    print(dict3)

 





练习题

1、使用while循环输入 1 2 3 4 5 6     8 9 10

2、求1-2+3-4+5 ... 99的所有数的和

3、用户登陆(三次机会重试):总共3此机会,3次都错误则退出

 4、猜数字游戏:有3次机会,如果3次中没有猜中给予提示,3次都没有猜中,鼓励!
 
参考答案:
1.使用while循环输入 1 2 3 4 5 6     8 9 10
#!/usr/bin/env python
#-*- coding:utf-8 -*-

num = 1
while True:
    if num <=10:
        if num == 7:
            pass
        else:
            print num
        num += 1

执行结果:

1
2
3
4
5
6
8
9
10

 

 
2、求1-2+3-4+5 ... 99的所有数的和
 
方法1:
sum100 = 0
start = 1
while start < 100:
    temp = start % 2
    if temp == 1:
        sum100 = sum100 + start
    else:
        sum100 = sum100 - start
    start += 1
print(sum100)

 

方法2:

#!/usr/bin/env python
#coding:utf-8


sum100 = 0
start = 1
while start < 100:
    temp = start % 2
    if temp == 1:
        if start == 1:
            s = str(start)
        else:
            s = s + "+" + str(start)
        sum100 = sum100 + start
    else:
        s = s + "-" + str(start)
        sum100 = sum100 - start
    start += 1

print(s)
print(sum100)

 


3、用户登陆(三次机会重试):总共3此机会,3次都错误则退出

i = 0
while i < 3:
    user= raw_input("username: ")
    pwd = raw_input("password: ")
    if user == "bob" and pwd == "123":
        print "yes"
        break
    else:
        print "try again..."
    i += 1

执行结果:

username: bob
password: 12345
try again...
username: bob
password: 1234
try again...
username: bob
password: 123
yes

 

 4、猜数字游戏:有3次机会,如果3次中没有猜中给予提示,3次都没有猜中,鼓励!

方法1:使用random模块和for循环

#!/usr/bin/env python
#-*- coding:utf-8 -*-
import random   #随机模块
rand_num = random.randrange(10)  #从0-9随机选择一个数字

for i in range(3):
    guess_num = int(raw_input("请猜测数字:"))
    if guess_num == rand_num:
        print "太棒了你猜对了"
        break
    elif guess_num > rand_num:
        print "你猜测的有点大了,请尝试小点的数字"
    else:
        print "你猜测的有点小了,请尝试大点的数字"
else:
    print "不要灰心,这次只是运气不好,请下次尝试"

print "这个真正的数字是:%d" % rand_num

执行结果:

请猜测数字:7
你猜测的有点小了,请尝试大点的数字
请猜测数字:9
太棒了你猜对了
这个真正的数字是:9

 

random模块部分内容:

random.randrange([start,] stop [,step])方法:返回指定递增基数集合中的一个随机数,基数缺省值为1。例如:random.randrange(0, 101, 2),随机选取0到100间的偶数:

 

 

方法2:使用random模块和while循环

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import random
rand_num = random.randrange(10)
try_cout = 0

while try_cout < 3:
    guess_num = int(raw_input("请输入猜测的数字:"))
    if guess_num > 10:
        print "输入的数字超出范围了"
        continue
    if guess_num == rand_num:
        print "哇!太棒了,你猜对了"
        break
    elif guess_num < rand_num:
        print "你猜的数字有点小了,请尝试大点的数字"
    else:
        print "你猜的数字有点大了,请尝试小点的数字"

    try_cout +=1
else:
    print "不要灰心,你这次只是运气不好,请下次尝试"
print "这个真正的数字是:%d"  % rand_num
#当执行到guess_num> 10 如果你输入的是大于10的数字那么将会执行continue,就会跳出档次循环,没有执行try_cout +=1 所以没有计数!

 

执行结果:

请输入猜测的数字:6
你猜的数字有点大了,请尝试小点的数字
请输入猜测的数字:4
你猜的数字有点大了,请尝试小点的数字
请输入猜测的数字:3
哇!太棒了你猜对了
这个真正的数字是:3

 

 

 

posted @ 2019-06-18 21:52  钟桂耀  阅读(466)  评论(0编辑  收藏  举报