初识Python第三天(二)

2.2 OrderedDict有序字典

 1 import collections
 2 dic = collections.OrderedDict() 
 3 dic['k1'] = 'v1'
 4 dic['k2'] = 'v2'
 5 dic['k3'] = 'v3'
 6 print(dic)
 7 dic.move_to_end('k1')  #将'k1'放到字典末尾
 8 print(dic)
 9 
10 #OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
11 #OrderedDict([('k2', 'v2'), ('k3', 'v3'), ('k1', 'v1')])
move_to_end将指定元素放到最后
 1 import collections
 2 dic = collections.OrderedDict()
 3 dic['k1'] = 'v1'
 4 dic['k2'] = 'v2'
 5 dic['k3'] = 'v3'
 6 print(dic
 7 
 8 dic.popitem() 
 9 print(dic)
10 
11 #OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
12 #OrderedDict([('k1', 'v1'), ('k2', 'v2')])
popitem 移除最新添加的元素(后进先出)
 1 #移除指定元素,可将移除的元素赋值给自己
 2 import collections
 3 dic = collections.OrderedDict()
 4 dic['k1'] = 'v1'
 5 dic['k2'] = 'v2'
 6 dic['k3'] = 'v3'
 7 print(dic)
 8 dic.pop('k2')
 9 print(dic)
10 
11 #OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
12 #OrderedDict([('k1', 'v1'), ('k3', 'v3')])
13 
14 import collections
15 dic = collections.OrderedDict()
16 dic['k1'] = 'v1'
17 dic['k2'] = 'v2'
18 dic['k3'] = 'v3'
19 print(dic)
20 ret = dic.pop('k2')
21 print(ret)   #将移除的元素赋值给变量
22 
23 #OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
24 #v2 
pop移除指定元素
 1 import collections
 2 dic = collections.OrderedDict()
 3 dic['k1'] = 'v1'
 4 dic['k2'] = 'v2'
 5 dic['k3'] = 'v3'
 6 print(dic)
 7 dic.setdefault('k4', '66')  #setdefault设置默认值,如果对象后面不加参数默认为None
 8 print(dic)
 9 
10 #OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
11 #OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3'), ('k4', '66')])
setdefault设置默认值
 1 import collections
 2 dic = collections.OrderedDict()
 3 dic['k1'] = 'v1'
 4 dic['k2'] = 'v2'
 5 dic['k3'] = 'v3'
 6 print(dic)
 7 dic.update({'k1':'v111', 'k10':'v10'})  
 8 print(dic)
 9 
10 #OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
11 #OrderedDict([('k1', 'v111'), ('k2', 'v2'), ('k3', 'v3'), ('k10', 'v10')])
update更新原有的数据

2.3 默认字典

import collections
dic = collections.defaultdict(list) #设置类型为列表类型
dic['k1'].append('alex')
print(dic)

#defaultdict(<class 'list'>, {'k1': ['alex']})

2.4可命令元组

 1 #可命令元组
 2 import collections
 3 MytupleClass = collections.namedtuple('MytupleClass',['x', 'y', 'z'])  #创建一个类,类名为MytupleClass
 4 obj = MytupleClass(11,22,33)
 5 print(obj.x) #直接通过命令元素去访问元组对应的元素
 6 print(obj[0]) #等同于上面这种方式,但是没有上面这种方式可读性强
 7 print(obj.y)
 8 print(obj.z)
 9 
10 #11
11 #11
12 #22
13 #33
View Code

2.5 deque双向队列

import collections
newdeque = collections.deque(['alex', 'eric', 'jack']) #创建一个双向队列
print(newdeque) #deque(['alex', 'eric', 'jack'])

newdeque.append('11')  #追加一个元素到队列
print(newdeque)  #deque(['alex', 'eric', 'jack', '11'])

newdeque.appendleft('22')  #追加一个元素到左侧
print(newdeque) #deque(['22', 'alex', 'eric', 'jack', '11'])

newc = newdeque.count('alex')  #对队列里某个元素进行计数
print(newc)  # 1

newdeque.extend(['44', '55'])  #扩展队列元素
print(newdeque)  #deque(['22', 'alex', 'eric', 'jack', '11', '44', '55'])

newdeque.extendleft(['aa', 'bb'])  #从左侧进行扩展
print(newdeque)  #deque(['bb', 'aa', '22', 'alex', 'eric', 'jack', '11', '44', '55'])



newdeque.insert(2, 'haha')  #插入到下标2的位置
print(newdeque)  #deque(['alex', 'eric', 'haha', 'jack'])

newdeque.reverse()  #顺序反转
print(newdeque)   #deque(['jack', 'haha', 'eric', 'alex'])

newdeque.rotate(3)  #将队列末尾3个元素反转到队列左侧
print(newdeque)  #deque(['haha', 'eric', 'alex', 'jack'])

2.5.1 deque双向队列,该对象与collections的deque实质是完全一样的效果,这里就不作演示了,使用方法如下:

1 import queue
2 q = queue.Queue(['a', 'b'])
 1 import queue
 2 newdeque = queue.Queue(3)  #设置队列长度为3,也就是队列里面只有3个任务,如果不设置队列长度,就可以有
 3 #无限个任务,直到内存耗尽
 4 newdeque.put(['1', '2'])  #放入第一个任务
 5 get1 = newdeque.get()    #获取第一个任务
 6 print(get1)              #['1', '2']
 7 
 8 newdeque.put(['a', 'b'])  #放入第二个任务
 9 get2 = newdeque.get()    #获取第二个任务
10 print(get2)              #['a', 'b']
11 
12 isempty = newdeque.empty()  #判断队列是否为空
13 print(isempty)             # True
14 
15 isfull = newdeque.full()  #判断多列是否已经满了
16 print(isfull)             #False
queue 单项队列

三.深浅拷贝

1 import copy  #导入拷贝模块
2 copy.copy()   #浅拷贝
3 copy.deepcopy()    #深拷贝
4 name = 'alex'
5 copyname = name   #赋值
 1 #浅拷贝
 2 import copy
 3 a1 = [10,'b1',[111,112],'ha',]
 4 a2 = copy.copy(a1)  #浅拷贝
 5 print(a1)
 6 print(a2)
 7 
 8 a1[1] = 11 #改变a1的值
 9 a1[2][0] = 1111  #改变a1内嵌列表的值,将a1的第2个下标的第0个下标值改变
10 print(a1)
11 print(a2)
12 print(id(a1))
13 print(id(a2))
14 print(id(a1[2][0]))
15 print(id(a2[2][0]))
16 
17 #[10, 'b1', [111, 112], 'ha']
18 #[10, 'b1', [111, 112], 'ha']
19 #通过下面的对比,发现浅拷贝对于内嵌多层数据类型的操作,如果多层数据类型值改变,浅拷贝的对象也会跟着改变
20 #[10, 11, [1111, 112], 'ha']
21 #[10, 'b1', [1111, 112], 'ha']
22 
23 #12542664
24 #12543688
25 
26 #7183888
27 #7183888
 1 #深拷贝
 2 import copy
 3 a1 = [10,'b1',[111,112],'ha',]
 4 a2 = copy.deepcopy(a1)  #深拷贝
 5 print(a1)
 6 print(a2)
 7 
 8 a1[1] = 11 #改变a1的值
 9 a1[2][0] = 1111  #改变a1内嵌列表的值,将a1的第2个下标的第0个下标值改变
10 print(a1)
11 print(a2)
12 print(id(a1))
13 print(id(a2))
14 print(id(a1[2][0]))
15 print(id(a2[2][0]))
16 
17 #[10, 'b1', [111, 112], 'ha']
18 #[10, 'b1', [111, 112], 'ha']
19 #结合上面的例子进行对比发现,对应深层拷贝,内嵌多层的数据类型的值,被改变,不会影响到另一方拷贝或被拷贝的对象
20 #[10, 11, [1111, 112], 'ha']
21 #[10, 'b1', [111, 112], 'ha']
22 #19030728
23 #19031752
24 #7118352
25 #1723483792

四.函数

函数定义主要有如下要点

1.def:表示函数的关键字

2.函数名:函数的名称,日后可根据函数名调用函数

3.函数体:函数中进行一系列的逻辑计算。

4.参数:为函数提供数据

5.返回值:当函数中执行完成后,可以给调用者返回数据

以上要点中,比较重要的有参数和返回值

 1 def func():  #创建一个函数,没有接收参数
 2     print('hello')
 3 
 4 func()   #直接执行函数
 5 #执行结果  hello
 6 
 7 foo = func  #创建一个对象
 8 foo()   #执行对象
 9 #执行结果 hello
10 
11 def func(arg):   #传入一个参数
12     print('hello %s' % arg)
13 
14 func('laiying')    #执行结果输出 hello laiying
15 
16 
17 def func(arg1,arg2):  #传入两个参数
18     print('hello %s, %s' % (arg1, arg2))
19 
20 func('laiying','good')  #执行结果输出 hello laiying, good
21 
22 
23 def func(*args):   #动态参数,多个参数,可以为空
24     print('hello %s' % (''.join(args)))
25 
26 func('laiying', '很棒', 'very good')  #执行结果输出hello laiying很棒very good
27 
28 
29 
30 #以下两种方式得到的效果相同
31 def show(*args,**kwargs):
32     print(args,type(args))
33     print(kwargs,type(kwargs))
34 show(11,22,33, n1= 88,n2='alex')
35 #结果输出(11, 22, 33) <class 'tuple'>{'n2': 'alex', 'n1': 88} <class 'dict'>
36 
37 
38 def show(*args,**kwargs):
39     print(args,type(args))
40     print(kwargs,type(kwargs))
41 a = [11, 22, 33, ]
42 b = {'n1':88, 'n2':'alex'}
43 show(*a, **b)
44 #结果输出(11, 22, 33) <class 'tuple'>{'n2': 'alex', 'n1': 88} <class 'dict'>

函数参数

1.形参变量只有在被调用时才分配内存单元, 在调用结束时,即可释放所分配的内存单元,因此,形参只在函数内部有效,

函数调用结束返回时主调用函数后则不能在使用该形参变量

2.实参可以是常量,变量,表达试,函数等,无论实参是何类型的量,在进行函数调用时,它们都必须有确定的值,

以便把这些值传送给行参,因此应预先用赋值,输入等办法使参数获得确定值

3.位置参数和关键字(标准调用:实参与行参位置必须一一对应,关键字调用:位置无需固定)

4.默认参数

5.参数组 *args 以元组的形式传入参数  **kwagrs以字典的形式传入参数

以上参数是以一个整体,元组,字典的方式传入,如果需要一次传入多个元素,但是又可以分开一个一个传入,可以使用以下方式

参数的传入规则  (位置参数,关键字参数)---------默认参数------------参数组

五.嵌套函数

# 创建嵌套函数
NAME = 'alex'
def global_test():   # 第一层定义的函数
    name = 'rain'
    print("global_test: ",name)
    def local_test():  #  第二层定义的函数
        name = 'jack'
        print("local_test: ",name)
        def test():   # 第三成第一的函数
            name = 'ying'
            print("test: ",name)
           
        test()
    local_test()
global_test()

#执行结果
global_test:  rain
local_test:  jack
test:  ying

#通过以上结果我们可以看出,嵌套函数的执行顺序是,先执行外层函数,然后依次执行内层中的嵌套函数, 内层中的函数不可在其他地方调用,只能在该函数中调用   

六:函数中global与nonlocal的作用

通过以上截图可以看出,只要通过global关键字将变量改为了全局变量,那么以前的那个全局变量就会被覆盖,以后在执行该变量时,执行的就是通过global从新定义的这个全局变量,

全局变量的范围就是整个程序

通过以上截图可以看出nonloacl关键字的作用就是,将上一层的变量修改为当前变量,只对上一层生效,不能对其它层生效

六.递归

在函数内部,可以调用其他函数,如果一个函数在内部调用自己本身,这个函数就是递归函数

 1 def calc(n):
 2     print(n)
 3     if int(n/2) == 0:
 4         return n
 5     return calc(int(n/2))
 6 calc(10)
 7 
 8 #执行结果
 9 10
10 5
11 2
12 1
13 
14 #根据以上结果,我们来分析一下执行的流程
15 1.给calc这个函数传入一个参数n为10
16 2.打印这个函数
17 3.if判断n是不是等0,如果n==0就终止这个函数,并给一个返回值n
18 4.终止自身函数的运行,然后调用自己,计算n/2,并将这个值给返回。
19 
20 5.重复以上执行流程,一直到n/2==0,就终止这个函数本身的运行,并return一个返回值n

递归问路

 1 person_list = ["alex","jakc","rain"]
 2 def ask_way(person_list):
 3     print('-'*60)
 4     if len(person_list) == 0:
 5         return "没有人知道"
 6     person = person_list.pop(0)
 7     if person == "rain":
 8         return "%s说:我知道,圆明园在海淀,下地铁就到" %person
 9     print("hi [%s],请问圆明园在什么地方" %person)
10     print("%s回答道:我不知道,你等在,我帮你问下一个人%s"%(person,person_list))
11     res = ask_way(person_list)
12     print("%s问的结果是:%res" %(person,res))
13     return res
14 res = ask_way(person_list)
15 print(res)
16 
17 ###########执行结果##########
18 ------------------------------------------------------------
19 hi [alex],请问圆明园在什么地方
20 alex回答道:我不知道,你等在,我帮你问下一个人['jakc', 'rain']
21 ------------------------------------------------------------
22 hi [jakc],请问圆明园在什么地方
23 jakc回答道:我不知道,你等在,我帮你问下一个人['rain']
24 ------------------------------------------------------------
25 jakc问的结果是:'rain说:我知道,圆明园在海淀,下地铁就到'es
26 alex问的结果是:'rain说:我知道,圆明园在海淀,下地铁就到'es
27 rain说:我知道,圆明园在海淀,下地铁就到

递归特性

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

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

3.递归效率不高,递归层次过多会导致栈溢出

(在计算机中,函数调用是通过栈(stack)这个数据结果实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧,

由于栈的大小不是无限的,所以,递归调用的次数过多,会会导致栈溢出)

七.lambda & map

lambda书写格式:参数:表达式   直接得出一个结果,赋值给一个变量

lamdba存在的意义是对简单函数的简洁表达

1 func = lambda a:a+1     #创建形式参数a
2 ret = func(1)     #函数内容,a+1 并把结果retun回去
3 
4 print(ret)
5 #打印输出 2
6 
7 map1 = map(lambda x:x+100, [11,22,33])  #map(函数,'参数')
8 print(list(map1))
9 #结果输出 [111, 122, 133] ,python2.x可以直接看到结果,python3.x需要转换成list才能看到结果
原文地址:https://www.cnblogs.com/YingLai/p/5911279.html