python之高级特性

1.迭代

1.定义

如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。

2.迭代方式

在Python中,迭代是通过for ... in来完成的

Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上。

只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以迭代,

但因为dict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。

默认情况下,dict迭代的是key

dict={'a':1,'b':2,'c':3}
for key in dict:
    print(key)

如果要同时迭代key和value,可以用for k, v in d.items():

dict={'a':1,'b':2,'c':3}
for key,value in dict.items():
    print(value)

由于字符串也是可迭代对象,因此,也可以作用于for循环:

str='abc'
for k in str:
    print(k)

3.判断是否可以迭代

方法是通过collections模块的Iterable类型判断:

from  collections import Iterable
print( isinstance('abc', Iterable))      # str是否可迭代
print(isinstance([1,2,3], Iterable))               # list是否可迭代
print(isinstance(123, Iterable))         # 整数是否可迭代)

总结:常见的数据类型,除了整形数和bool类型,其他均可迭代

4.迭代知识补充

如果要对 list 实现类似 Java 那样的下标循环怎么办?
python内置的枚举方法enumerate,把一个 list 变成索引­元素对(枚举)

for i, value in enumerate(['A', 'B', 'C']):
    print (i, value)

2.列表生成式

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

1.基本语法

[变量表达式   for   变量    in   表达式 ]

变形:

       1). [i**2  for  i  in  range(2,10,2) ]
       2). [fun(i)  for  i  in  range(2,10,2)]
       3). [i**2  for  i  in  range(2,10,2)  if i%3==0]
       4). [fun(i)  for  i  in  range(2,10,2)  if i%3==0]
       5). [fun(i)  for  i  in  range(2,10,2)  if isFun(i)]
       6). [fun1(i)  isFun(i)  else  fun2(i)  for  i  in  range(2,10,2)]

例:
a = [x ** 2 for x in range(1, 10)]
b = [x * x for x in range(1, 11) if x % 2 == 0]
c = [m + n for m in 'ABC' for n in '123']
d = {'Java': "99", 'C': "99", 'C++': "99"}
L = [k + '=' + v for k, v in d.items()]

print(a)
print(b)
print(c)
print(L)

2.练习

1. 找出1~10之间所有偶数, 并且返回一个列表, (包含以这个偶数为半径的圆的面积)

1)一般代码

import math
li = []
for r in range(2,11,2):  #[2,4,6,8,10]
    square = math.pi * r * r
    li.append(square)
print(li)

2)列表生成式

import math
print([math.pi*i*i for i in range(2,11,2)])

3) 列表生成式实现, 将要返回的操作抽象为一个函数

import math
def s(r):
        ss=math.pi*r*r
        return ss
print([s(r) for r in range(2,11,2)])

2. 找出1~100之间所有的质数.
    判断num是否为质数, 如果为质数, 返回True, 否则返回False;
    什么是质数?
        只能被1和本身整除的数, 就是质数.
        方法:循环:
            依次判断num能否被(2,num)整除,
            如果能被其中一个数整除,不是质数.
            当循环结束, 都没有发现能被整除的数, 那么就是质数.

def isPrime(num):
    for i in range(2, num):
        if num % i == 0:
            return False
    else:
        return True

print([i for i in range(2, 101) if isPrime(i)])

3. 找出1~100之间所有奇数, 并且返回一个列表,
                   (如果能被3整除, 返回返回该数的平方, 否则返回该数的三次方)

print([i*i if i%3==0 else i*i*i for i in range(1,100,2) ])

4.实现矩阵转置

1)列表生成式

li=[
    [1,2,3],
    [4,5,6],
    [7,8,9]
]
print([[n[i] for n in li] for i in range(3)])

2)内置zip

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

print(list(zip(*li)))

3.字典生成式

1.基本语法

{key:value for 变量 in  表达式}

2.练习

1. 假设有20个学生,学生分数在60-100之间,筛选出成绩在90分以上的学生

import random
stuInfo = {"westos"+ str(i):random.randint(60,100) for i in range(20)}
print({ name:score for name, score in stuInfo.items() if score > 90 })

2.将字典的key值和value值调换

d = {'a':'apple', 'b':'bob', 'c':'come'}

print({v:k for k,v in d.items()})

3..大小写计数合并 : key值最终全部为小写

d1 = {'A':10, 'b':3, 'a':5, 'B':8, 'd':1}

print({k.lower(): d1.get(k.upper(),0)+d1.get(k.lower(),0) for k,v in d1.items()})

3.集和生成式

1.基本语法

{表达式 for 变量 in  表达式}

2.练习

求1~7的平方

s = {1,2,3,4,5,6,7}
# 集合生成式
print({i**2 for i in s })

通过运行结果发现,集和是无序的

4.生成器

1.为什么需要生成器

通过列表生成式,我们可以直接创建一个列表,受到内存限制,列表容量肯定是有限的

创建一个包含 100 万个元素的列表,占用很大的存储空间;

2.定义

 在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的 list,从而节省大量的空间。

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

3.怎么创建生成器

1)生成器最快实现的方式:通过列表生成式改写,把一个列表生成式的 [] 改成 (). 一边循环, 一边计算的机制.

例:判断2~num之间有多少个质数

def isPrime(num):
    for i in range(2, num):
        if num % i == 0:
            return  False
    else:
        return True
primeLi =  (i for i in range(2,10) if isPrime(i))
print(primeLi)

我们会发现,使用生成器后打印出来的是一个生成器对象

2)使用yield方法

在一个一般函数中使用yield关键字,可以实现一个最简单的生成器,此时这个函数变成一个生成器函数。yieldreturn返回相同的值,区别在于return返回后,函数状态终止,而yield会保存当前函数的执行状态,在返回后,函数又回到之前保存的状态继续执行。

def fun():
    print('step 1')
    yield "yield1"
    print('step 2')
    yield  'yield2'
    print('step3')
    yield 'yield3'

g = fun()
print(g)   ###函数中有yield, 返回值是一个生成器.
next(g)     #####生成器函数默认不执行函数内容, 当next(g)时, 才执行函数内容.
                        #####执行函数时, 一直执行, 遇到yield停止。 默认情况不会显示yield后面的内容,
print(next(g))    #### 如果要显示print(next(g))

 

4.读取内容

1)next方法

每执行一次next方法,就会生成一次运行的结果,不会一次性全出结果

def isPrime(num):
    for i in range(2, num):
        if num % i == 0:
            return  False
    else:
        return True
primeLi =  (i for i in range(2,10) if isPrime(i))
print(primeLi)

print(next(primeLi))
print(next(primeLi))

2)使用for循环

def isPrime(num):
    for i in range(2, num):
        if num % i == 0:
            return  False
    else:
        return True
primeLi =  (i for i in range(2,10) if isPrime(i))
print(primeLi)

for x in primeLi:
    print(x)

我们会发现,一次遍历了所有结果

5.给生成器传值

 f.send(' '), 给生成器传递值;
           给yield所在位置发送一个数据, 直到遇到下一个yield停止.

例:实现迷你机器人聊天

def chat_robot():
    res = ''
    while True:
        receive = yield res
        if 'age' in receive:
            res = "年龄保密"
        elif 'name' in receive:
            res = "siri"
        else:
            res = "i don't know what you say"

def main():
    # 生成器对象
    Robot = chat_robot()
    next(Robot)
    while True:
        send_data = input("粉条>>:")
        if send_data == 'q' or send_data == 'bye':
            print("不聊了, 我也撤了.....")
            break
        print(Robot.send(send_data))
main()

5.练习

1.斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)
以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,
斐波纳契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1963年起出版了以
《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。

def fib(num):        """num表示将来显示几个fib数列"""
    
    a,b,count = 0,1,0    # count代表显示的已经 
                          # a代表第一个数, b代表第二个数, count代表已经显示的fib个数,当前为0.
    while count < num:    # 如果当前显示的个数小于需要显示的格式, 则显示b, 并且计算出下一个要显示的数。
        yield  b
        a, b = b, a+b
        count += 1           # 已经显示的次数加1;


# 生成器: 如果函数中有yield, 那么这个函数的返回值就是一个生成器;
res=fib(100)
print(next(res))
print(next(res))

###或者for循环

for  x   in  res

         print(x)

 

 

生成器fib()执行的过程分析:
#       执行语句 f = fab(100) 时,并不会马上执行 fib() 函数的代码块,而是首先返回一个 iterable 对象(即生成器)!
#       在 for 循环语句执行时或者next(),才会执行 fib() 函数的代码块。
#       执行到语句 yield b 时,fib() 函数会返回一个迭代值,直到下次迭代前,
#       程序会回到 yield b 的下一条语句继续执行,然后再次回到 for 循环,如此迭代直到结束。
#       看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。
# 由此可以看出,生成器通过关键字 yield 不断的将迭代器返回到内存进行处理,而不会一次性的将对象全部放入内存,
# 从而节省内存空间。

 

2.yield实现python3中的range

def myRange(start, stop, step=1):
    while stop > start:
        yield  start
        start =  start + step

g = myRange(1,10,2)
for i in g:
    print(i)

 

3.合法IP判断
"""
题目描述:
    现在IPV4下用一个32位无符号整数来表示,一般用点分方式来显示,点将IP地址分成4个部分,每个部分为8位,表示成一个无符号整数(因此不需要用正号出现),如10.137.17.1,是我们非常熟悉的IP地址,一个IP地址串中没有空格出现(因为要表示成一个32数字)。
现在需要你用程序来判断IP是否合法。

输入描述:
    输入一个ip地址
输出描述:
    返回判断的结果YES or NO


示例1:
输入
    10.138.15.1
输出
    YES

1)正向思维

ip=input('请输入要判定的ip:')
li=(ip.split('.'))
if len(li) != 4:
    print('NO')
    exit()
else:
    for i in li:
        if int(i)>0  and  int(i)<255:
            pass
        else:
            print('NO')
            break
    else:
        print('OK')

2)逆向思维

ip=input('请输入要判定的ip:')
li=(ip.split('.'))
if len(li) != 4:
    print('NO')
    exit()
else:
    for i in li:
        if  int(i)<=0 or  int(i)>=257:
            print('NO')
            exit()
    else:
        print("YES")

 

4.密码验证合格程序

题目描述: 密码要求
    1.长度超过8位
    2.包括大小写字母.数字.其它符号,以上四种至少三种
    3.不能有相同长度超2的子串重复
    说明:长度超过2的子串


输入描述:
    一组或多组长度超过2的子符串。每组占一行
输出描述:
    如果符合要求输出:OK,否则输出NG

def checklen(s):
    if len(s) > 8:
        return True
    else:
        return False


def check2(s):
    flag_up, flag_low, flag_digit, flag_other = 0, 0, 0, 0
    for i in s:
        if i.isupper():
            flag_up = 1
        elif i.islower():
            flag_low = 1
        elif i.isdigit():
            flag_digit = 1
        else:
            flag_other = 1

    if (flag_up + flag_low + flag_digit + flag_other) >= 3:
        return True
    else:
        return False


def check3(s):
    for i in range(len(s) - 3):
        if s.count(s[i:i + 3]) > 1:
            return False
    return True


while True:
    s = input()
    if s == 'quit':
        break
    if checklen(s) and check2(s) and check3(s):
        print ("OK")
    else:
        print ("NG")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值