码迷,mamicode.com
首页 > 编程语言 > 详细

第四天 内置函数2 随机码 装饰器 迭代器、生成器 递归 冒泡算法 JSON

时间:2017-01-12 12:56:40      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:选择   模板   固定   需要   接受   对比   lis   round   二次   

 

关于函数的return

 

li = [11,22,33,44]

 

def f1(arg):

    arg.append(55)

 

li = f1(li)

 

print(li)

 

因为li = f1(li) 实际赋值的是f1的return,那么在这种情况下函数f1并未定义return,所以默认返回None

 

因此li的值应该是none

 

 

 

如果是

 

li = [11,22,33,44]

 

def f1(arg):

    arg.append(55)

 

f1(li)

 

print(li)

 

因为函数传递的参数实际是参数的引用,因此在函数中对参数坐的变更会影响原来的参数,因此返回的是11,22,33,44,55

 

 

 

 

将字符串转换为特定编码的字节类型

 

s = "刘博"

bytes(s,encoding="utf-8")

 

 

 

内置函数补充

 

callable() 判断对象是否可以被执行,函数可以被执行

 

 

 

chr()  将编码表中的序列转化为对应的字符,2.7内特指ASCII码

ord()  将编码表中的字符转化为对应的序号,2.7内特制ASCII码

 

 

 

随机验证码

 

import random #这个函数用来随机生成数字

 

tem = random.randrange(65,91) #指定随机生成数字的范围

 

c = chr(tem) #然后我们可以使用chr(i)的方式将i转换为对应的字符

 

在ASCII码表中65 - 91代表的是26个字母的大小写

 

如果一次生成多位的随机码,则可以按如下写法

li = []

for i in range(6):

    tem = random.randrange(65,91)

    c = chr(tem)

    li.append(c)

"".join(li)   #将生成的列表形成字符串

 

 

如果需要有数字则

 

li = []

for i in range(6):

    if  i == 2 or i == 4:

        tem = random.randrange(0,10)

        li.append(str(tem))        #因为在向列表中添加元素时,需要使用字符串类型,因此ASCII中0-10是数字因此需要将其转为字符串类型

    else:

        tem = random.randrange(65,91)

        c = chr(tem)

        li.append(c)

result = "".join(li)   #将生成的列表形成字符串

print(result)

 

 

上面的例子中数字的位置是固定的,如果希望将随机数做的跟彻底即数字的位置都是随机的

 

li = []

for i in range(6):

    r = random.randrange(0,6)

    if  r == 3 or r == 2:

        tem = random.randrange(0,10)

        li.append(str(tem))        #因为在向列表中添加元素时,需要使用字符串类型,因此ASCII中0-10是数字因此需要将其转为字符串类型

    else:

        tem = random.randrange(65,91)

        c = chr(tem)

        li.append(c)

result = "".join(li)   #将生成的列表形成字符串

print(result)

 

 

 

 

 

 

complie() 

eval()

exec()

 

任何一个python文件,计算机都要经过读取成字符串,编译,执行三个阶段。

 

complie()就是用来编译这个字符串的动作

s = "print(123)"         #s的值是字符串

r = complie(s,"<string>","exec)"   #r的值就是s编译后的结果,其中complie中s的位置也可以是一个文件名,如果是文件名就不需要后面的string参数,exec参数有3种值:single eval exec。其中如果选择single模式,则拿到的字符串会编译成单行的程序,如果是eval则会编译成表达式,如果是exec则按照原来的python代码编译

 

exec() 用来执行编译后的代码,和complie何用,先用complie编译,然后用exec执行。exec可以执行所有的python的命令,exec只是执行没有返回值,因此用exec运行一个表达式,是拿不到结果的,例如exec(“7+8+9”),只是执行但是结果是拿不到的。在执行代码的时候exec可以接受代码或者字符串。

 

eval()用来将字符串编译为表达式,例如  s = "8*8"  r = eval(s) , print(r)的时候会返回为64,eval只能执行表达式,eval有返回值,如果用eval(“7+8+9”),是能返回结果的,这点比exec强,对比exec。

 

 

 

dir() 快速获取一个对象 一个类中的功能   print(dir(dict)),查看字典这个函数中提供的功能

 

help() 获取一个对象提供的功能的详细解释,dir仅介绍功能名,help有解释。

 

divmod()  用来以元组的形式获取一个数除以另一个数的整数和余数,r = divmod(97,10) ,print(r) 返回(9,7),因为默认返回永远都是2个数,因此可以使用n1,n2 = divmod(97,10) 会自动给n1 = 9 ,n2 = 7

 

enumerate() 序列化

 

instance()  对象是类的实例,即 s = “alex” 那么alex是基于str这个类创建的对象,因此alex就是类str的一个实例,类是一个模板,而对象是对这个模板的实例。s = "alex"  r = isinstance(s,str)判断s是否是str这个类的实例,print(r)会返回True

 

filter() filter(函数,可迭代对象) 在执行filter的时候,首先会循环可迭代对象,在每次循环的内部会执行第一个参数所填写的函数,并拿到函数的结果,如果结果为真,则会把这次循环的元素添加到一个列表中

li = [11,22,33,44]

def f1(a)

    if a > 22

        return True

 

ret = filter(f1,li)

print(list(ret))

 

会返回[33,44],因此filter是基于提供的函数对可迭代对象进行筛选。

上面的filter而已用lambda表达式来实现

 

li = [11,22,33,44]

ret = filter(lambda a : a>22,li)

print(list(ret))

 

 

 

map() map(函数,可迭代对象),在执行map的时候,首先会循环可迭代函数,然后再每次循环的结果代入之前传递的函数中,并运行函数中定义的返回结果,将其追加到一个新的列表中

 

 

li = [11,22,33,44]

def f1(a):

    return a + 100

ret = map(f1,li)

 

print(list(ret))

 

结果就是[111,122.133.144]

 

同样可以使用lambda表达式

 

li = [11,22,33,44]

ret = map(lambda a : a+100 ,li]

print(list(ret))

 

 

 

filter() 函数的返回为True,则将结果加入列表

map() 将函数的结果加入列表

 

 

 

 

globals() 代表所有的全局变量,输出类型为字典,print(globals())打印当前代码中所有的全局变量以字典类型输出

locals() 代表所有的局部变量,输出类型为字典,print(local())打印当前代码中所有的局部变量以字典类型输出

 

hash() 生成对应内容的hash值   s=123 print(hash(s)),在python存储字典key的时候都是现将key进行hash算法之后再存储,因为hash算法算出的值是一个固定长度的,因此无论key有多长实际在存储时是同样长度的值。所有的语言都是这么操作的。这样有利于存储,也有利于查找。

 

len() 查看变量的长度,在python3中按照字符计算,在python2.7中按字节计算,因此在python3中如果想要按字节算长,应先将变量变为字节。

s = “李杰”

print(len(s))  结果为2按字符,

 

s = “李杰”

b = bytes(s,encoding=“utf-8”)

print(b)         结果为6按字节

 

max() 查找序列中的最大值

min() 查找序列中的最小值

sum() 序列求和

 

 

memoryview() 和内存地址相关的一个类

 

object() 是所有类的父类

 

pow() 求平方,一般写法为2**10代表2的10次方,同时也看而已写为pow(2,10)

 

range() 指定一个范围

 

reversed() 翻转

 

round()  将一个小数四舍五入

 

slice() 切片

 

sort() 排序 sort(列表) 等于 列表.sort

 

zip()  传入多个列表,zip会将所有列表的第一个元素拼为一个元组,第二个元素拼为一个元组以此类推。当元素长度不一样的时候,只会拼接到列表 元素最少的那个位置

 

l1=["liubo",23,19]

l2=[33,55]

l3=["aa","cc",22,55]

l4=zip(l1,l2,l3)

print(list(l4))

输出结果为

[(‘liubo‘, 33, ‘aa‘), (23, 55, ‘cc‘)]  # 只到了拼接到第二个元素,因为l2只有2个元素

 

 

 

 

深色框是要会的,打勾的是用的比较常用的

 

 

JSON 可以将可以将字符串根据其形式转换为对应的类型,也可以将对应类型的数据按照原格式转换为字符串

 

s = "[11,22,33,44]"   # 这是一个字符串而不是列表

n = json.loads(s)  # 通过这种方法,就将s的字符串转换成了列表,字典也可以,可以将文件中对应的格式写入python成为特定的数据类型

 

s = [11,22,33]  # 这是一个列表

n = json.dumps(s) # 通过这个就可以将其转化为字符串,但是格式仍然是列表的格式就像上例中的s ,比如可以用他来讲内容写入文件,写入文件必须要字符串 

 

转换通常元组是不行的,因为转化是跨语言的,但是元组的()是python独有的

使用转换时,如果想要通过loads将字符串转换成字典或列表,那么里面的字符串内部的字符串元素必须用双引号

 

 

 

装饰器

 

函数开发有开放封闭规则,即对函数本身是封闭的不能被随便改写,但是在外部是可以开放调用这个函数的。但是如果要批量修改多个函数,就需要用到装饰器。即在不改变原有函数的情况下,增加函数的功能

 

定义一个s1.py,代码如下

def outer(func):

    def inner():

        print("log")

        return func()

    return inner

 

@outer

def f1():

    print("F1")

 

@outer

def f2():

    print("F2")

 

 

@outer

def f3():

    print("F3")

 

这样当别人在通过调用f1函数时会首先执行outer函数中的功能。outer函数就是装饰器,在不改变f1函数功能的情况下,通过装饰器增加了f1函数的功能。

 

调用方法:

新建一个py文件

import s1       # 将之前创建的s1导入到代码中

s1.f1() # 调用s1代码中的f1函数

 

结果是

log # outer装饰器的输出

F1 # f1函数的输出

 

 

装饰器必备知识点:

 

1、

def f1():

    print(123)

 

def f1():

    print(456)
 

f1()

此时执行f1会打印456,因为python是一行一行加载代码,因此第二次f1会将f1指向print(456)的方法

 

 

2、

def f1():

    print(123)

 

def f2(xxx):

    xxx()

 

 

f2(f1)

 

函数的参数可以是另一个函数,因此输出123

 

 

@ + 函数名 就是装饰器

@outer的功能

1、自动执行outer函数并且将它下面的函数名f1当做参数传递(函数名代指整个函数,函数名()才是执行函数)

2、将outer函数的返回值重新赋值给f1

 

因此:

 

def outer(func):

    def inner():

        print("before")

    return inner

 

@outer

def f1():
    print("F1")

 

执行上面的函数的过程是

1、首先系统会自动执行outer函数,并将f1作为参数传递给outer函数

2、outer函数内部定义了一个新的函数inner,该函数打印before

3、outer函数返回了inner函数

4、outer函数将返回值inner函数重新赋值给f1

5、此时f1()的函数内容被替换为了inner的内容

6、因此执行f1()函数时打印before而不是F1

 

 

 

[email protected][email protected][email protected]是outer的内层函数的作用

 

def outer(func):

    def inner():

        print("before")

        func()

   print("after")

    return inner

 

@outer

def f1():

    print(123)

 

在上面outer函数内层函数中的func实际就是f1的原函数体,[email protected][email protected]执行f1最后执行after

 

 

 

定义函数,未调用,函数内部不执行

 

函数名代指整个函数,函数名()才是执行函数

 

def outer(func):

    def inner():

        print("before")

        func()

   print("after")

    return inner

 

@outer

def f1():

    print(123)

因此这个例子中,outer函数的返回值必须是inner而不是inner(),因为这样做的目的时要将inner这个函数的函数体返回给f1,否则如果return inner(),则是返回的inner函数定义的返回值,而这个函数我们并未指定返回,默认返回为None。这样函数f1也就被替换为none。即便inner定义了返回值,也不是我们所要的。我们要的是inner函数体而不是返回值

 

 

 

如果原函数定义了返回值

那么在装饰器中的函数inner就会没有返回值,因为inner中只执行了func()而没有获取他的返回值。因此需要我们将这个返回值获取到

所以完整的装饰器写法应该入下

 

 

def outer(func):

    def inner():

        print("before")

        r = func() # 执行原函数,并获取原函数返回值

   print("after")

   return r  # 将原函数的返回值返回    

    return inner

 

 

 

如果原函数定义了参数

 

装饰器的函数应该使用万能参数来解决原函数带参数的问题。

 

def outer(func):

    def inner(*args,**kwargs):

        print("before")

        r = func(*args,**kwargs) # 此处python会直接将inner中的参数传递到func中。

   print("after")

   return r  # 将原函数的返回值返回    

    return inner

 

 

 

 

 

 

递归

 

一个函数在内部调用自己,就是递归。

递归特性的要求:

1、必须有一个明确的结束条件

 

 

 

2、每次进入更深一层递归时,问题规模相比上次递归都应有所减少

 

 

 

3、递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以递归调用次数过多,会导致栈 溢出)

第四天 内置函数2 随机码 装饰器 迭代器、生成器 递归 冒泡算法 JSON

标签:选择   模板   固定   需要   接受   对比   lis   round   二次   

(0)
(0)
   
举报
评论 一句话评论(0
0条  
登录后才能评论!
© 2014 mamicode.com 版权所有 京ICP备13008772号-2
迷上了代码!