Python复习系列:Python基础知识(三) |
您所在的位置:网站首页 › 表达式3and5的值 › Python复习系列:Python基础知识(三) |
Python基础知识(三)
Python基础知识(三)(一)循环结构和选择结构1. 条件表达式2. 选择结构2.1 单分支选择结构2.2 双分支选择结构2.3 多分支选择结构2.4 选择结构的嵌套
3. 循环结构3.1 for循环和while循环3.2 break和continue语句
4. 综合案例解析
(二)函数1. 函数定义与调用基本语法2. 函数递归调用3. 函数参数3.1 位置参数3.2 默认值参数3.3 关键参数3.4 可变长度参数3.5 传递参数时的序列解包
4. 变量的作用域5. Lambda表达式6. 生成器函数设计要点7. 精彩案例解析
Python基础知识(三)
(一)循环结构和选择结构
1. 条件表达式
绝大部分合法的Python表达式都可以作为条件表达式。 在选择和循环结构中,条件表达式的值只要不是False、0(或0.0、0 j等)、空值None、空列表、空元组、空集合、空字典、空字符串、空range对象或其他空迭代对象,Python解释器均认为与True等价。 >>> if 666: #使用整数作为条件表达式 print(9) 9 >>> a = [3, 2, 1] >>> if a: #使用列表作为条件表达式 print(a) [3, 2, 1] >>> a = [] >>> if a: #空列表等价于False print(a) else: print('empty') empty >>> i = s = 0 >>> while i >> print(s) 55 >>> i = s = 0 >>> while True: #使用常量True作为条件表达式 s += i i += 1 if i > 10: #符合特定条件时使用break语句退出循环 break >>> print(s) 55 >>> s = 0 >>> for i in range(0, 11, 1): #遍历序列元素 s += i >>> print(s) 55(1)关系运算符 Python中的关系运算符可以连续使用,这样不仅可以减少代码量,也比较符合人类的思维方式。 >>> print(1>> print(12) True在Python语法中,条件表达式中不允许使用赋值运算符“=”,避免了误将关系运算符“==”写作赋值运算符“=”带来的麻烦。在条件表达式中使用赋值运算符“=”将抛出异常,提示语法错误。 >>> if a=3: #条件表达式中不允许使用赋值运算符 SyntaxError: invalid syntax >>> if (a=3) and (b=4): SyntaxError: invalid syntax(2)逻辑运算符 逻辑运算符and、or、not分别表示逻辑与、逻辑或、逻辑非。对于and而言,必须两侧的表达式都等价于True,整个表达式才等价于True。 对于or而言,只要两侧的表达式中有一个等价于True,整个表达式就等价于True;对于not而言,如果后面的表达式等价于False,整个表达式就等价于True。 逻辑运算符and和or具有短路求值或惰性求值的特点,可能不会对所有表达式进行求值,而是只计算必须计算的表达式的值。 >>> 3 and 5 #整个表达式的值是最后一个计算的子表达式的值 5 >>> 3 or 5 3 >>> 0 and 5 #0等价于False 0 >>> 0 or 5 5 >>> not [1, 2, 3] #非空列表等价于True False >>> not {} #空字典等价于False True 2. 选择结构常见的选择结构有单分支选择结构、双分支选择结构、多分支选择结构以及嵌套的分支结构,也可以构造跳转表来实现类似的逻辑。 循环结构和异常处理结构中也可以带有“else”子句,可以看作是特殊形式的选择结构。 2.1 单分支选择结构编写程序,输入使用空格分隔的两个整数,然后按升序输出。 x = input('Input two number:') a, b = map(int, x.split()) if a > b: a, b = b, a #序列解包,交换两个变量的值 print(a, b) 2.2 双分支选择结构求解鸡兔同笼问题。 jitu, tui = map(int, input('请输入鸡兔总数和腿总数:').split()) tu = (tui - jitu*2) / 2 if int(tu) == tu: print('鸡:{0},兔:{1}'.format(int(jitu-tu), int(tu))) else: print('数据不正确,无解')Python还提供了一个三元运算符,并且在三元运算符构成的表达式中还可以嵌套三元运算符,可以实现与选择结构相似的效果。语法为 value1 if condition else value2当条件表达式condition的值与True等价时,表达式的值为value1,否则表达式的值为value2。 >>> b = 6 if 5>13 else 9 #赋值运算符优先级非常低 >>> b 9 2.3 多分支选择结构使用多分支选择结构将成绩从百分制变换到等级制。 def func(score): if score > 100 or score = 90: return 'A' elif score >= 80: return 'B' elif score >= 70: return 'C' elif score >= 60: return 'D' else: return 'F' 2.4 选择结构的嵌套使用嵌套选择结构将成绩从百分制变换到等级制。 def func(score): degree = 'DCBAAE' if score > 100 or score = 0: return degree[index] else: return degree[-1] 3. 循环结构Python主要有for循环和while循环两种形式的循环结构,多个循环可以嵌套使用,并且还经常和选择结构嵌套使用来实现复杂的业务逻辑。 while循环一般用于循环次数难以提前确定的情况,当然也可以用于循环次数确定的情况; for循环一般用于循环次数可以提前确定的情况,尤其适用于枚举或遍历序列或迭代对象中元素的场合。 对于带有else子句的循环结构,如果循环因为条件表达式不成立或序列遍历结束而自然结束时则执行else结构中的语句,如果循环是因为执行了break语句而导致循环提前结束则不会执行else中的语句。 两种循环结构的完整语法形式分别为: while 条件表达式: 循环体 [else: else子句代码块] 和 for 取值 in 序列或迭代对象: 循环体 [else: else子句代码块] 3.1 for循环和while循环编写程序,输出1~100之间能被7整除但不能同时被5整除的所有整数。 for i in range(1, 101): if i%7==0 and i%5!=0: print(i)编写程序,打印九九乘法表。 for i in range(1, 10): for j in range(1, i+1): print('{0}*{1}={2}'.format(i,j,i*j), end=' ') print() #打印空行 3.2 break和continue语句一旦break语句被执行,将使得break语句所属层次的循环提前结束; continue语句的作用是提前结束本次循环,忽略continue之后的所有语句,提前进入下一次循环。 编写程序,计算小于100的最大素数。 for n in range(100, 1, -1): if n%2 == 0: continue for i in range(3, int(n**0.5)+1, 2): if n%i == 0: #结束内循环 break else: print(n) #结束外循环 break 4. 综合案例解析输入若干个成绩,求所有成绩的平均分。每输入一个成绩后询问是否继续输入下一个成绩,回答“yes”就继续输入下一个成绩,回答“no”就停止输入成绩。 numbers = [] while True: x = input('请输入一个成绩:') #异常处理结构,用来保证用户只能输入实数 try: #先把x转换成实数,然后追加到列表numbers尾部 numbers.append(float(x)) except: print('不是合法成绩') #下面的循环用来限制用户只能输入任意大小写的“yes”或者“no” while True: flag = input('继续输入吗?(yes/no)').lower() #lower函数将字符串中所有的大写字母转化为小写字母 if flag not in ('yes', 'no'): print('只能输入yes或no') else: break if flag=='no': break #计算平均分 print(sum(numbers)/len(numbers))编写程序,判断今天是今年的第几天。 import time date = time.localtime() #获取当前日期时间 print(date) year, month, day = date[:3] day_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] if year%400==0 or (year%4==0 and year%100!=0): #判断是否为闰年 day_month[1] = 29 if month == 1: print(day) else: print(sum(day_month[:month-1])+day)编写代码,输出由星号*组成的菱形图案,并且可以灵活控制图案的大小。 def main(n): for i in range(n): print((' * '*i).center(n*3)) for i in range(n, 0, -1): print((' * '*i).center(n*3))快速判断一个数是否为素数。 n = input("Input an integer:") n = int(n) if n in (2,3): print('Yes') #偶数必然不是素数 elif n%2 == 0: print('No') else: #大于5的素数必然出现在6的倍数两侧 #因为6x+2、6x+3、6x+4肯定不是素数,假设x为大于1的自然数 m = n % 6 if m!=1 and m!=5: print('No') else: for i in range(3, int(n**0.5)+1, 2): if n%i == 0: print('No') break else: print('Yes')编写程序,输入一个自然数n,然后计算并输出前n个自然数的阶乘之和1!+2!+3!+…+n!的值。 n = int(input('请输入一个自然数:')) #使用result保存最终结果,t表示每一项 result, t = 1, 1 for i in range(2, n+1): #在前一项的基础上得到当前项 t *= i #把当前项加到最终结果上 result += t print(result)编写代码,模拟决赛现场最终成绩的计算过程。有至少3个评委,打分规则为删除最高分和最低分之后计算剩余分数的平均分。 while True: try: n = int(input('请输入评委人数:')) if n >> demo(3, 4, 5) #按位置传递参数 3 4 5 >>> demo(3, 5, 4) 3 5 4 >>> demo(1, 2, 3, 4) #实参与形参数量必须相同 TypeError: demo() takes 3 positional arguments but 4 were given 3.2 默认值参数在调用带有默认值参数的函数时,可以不用为设置了默认值的形参进行传值,此时函数将会直接使用函数定义时设置的默认值,当然也可以通过显式赋值来替换其默认值。在调用函数时是否为默认值参数传递实参是可选的。 需要注意的是,在定义带有默认值参数的函数时,任何一个默认值参数右边都不能再出现没有默认值的普通位置参数,否则会提示语法错误。 带有默认值参数的函数定义语法如下: def 函数名(……,形参名=默认值): 函数体 >>> def say( message, times =1 ): print((message+' ') * times) >>> say('hello') hello >>> say('hello', 3) hello hello hello 3.3 关键参数关键参数主要指调用函数时的参数传递方式,与函数定义无关。通过关键参数可以按参数名字传递值,明确指定哪个值传递给哪个参数,实参顺序可以和形参顺序不一致,但不影响参数值的传递结果,避免了用户需要牢记参数位置和顺序的麻烦,使得函数的调用和参数传递更加灵活方便。 >>> def demo(a, b, c=5): print(a, b, c) >>> demo(3, 7) 3 7 5 >>> demo(a=7, b=3, c=6) 7 3 6 >>> demo(c=8, a=9, b=0) 9 0 8 3.4 可变长度参数可变长度参数主要有两种形式:在参数名前加1个*或2个** *parameter用来接收多个位置参数并将其放在一个元组中 **parameter接收多个关键参数并存放到字典中 # *parameter的用法 >>> def demo(*p): print(p) >>> demo(1,2,3) (1, 2, 3) >>> demo(1,2) (1, 2) >>> demo(1,2,3,4,5,6,7) (1, 2, 3, 4, 5, 6, 7) # **parameter的用法 >>> def demo(**p): for item in p.items(): print(item) >>> demo(x=1,y=2,z=3) ('y', 2) ('x', 1) ('z', 3) 3.5 传递参数时的序列解包传递参数时,可以通过在实参序列前加一个星号将其解包,然后传递给多个单变量形参。 >>> def demo(a, b, c): print(a+b+c) >>> seq = [1, 2, 3] >>> demo(*seq) 6 >>> tup = (1, 2, 3) >>> demo(*tup) 6 >>> dic = {1:'a', 2:'b', 3:'c'} >>> demo(*dic) 6 >>> Set = {1, 2, 3} >>> demo(*Set) 6 >>> demo(*dic.values()) abc如果函数实参是字典,可以在前面加两个星号进行解包,等价于关键参数。 >>> def demo(a, b, c): print(a+b+c) >>> dic = {'a':1, 'b':2, 'c':3} >>> demo(**dic) 6 >>> demo(a=1, b=2, c=3) 6 >>> demo(*dic.values()) 6 4. 变量的作用域变量起作用的代码范围称为变量的作用域,不同作用域内变量名可以相同,互不影响。 在函数内部定义的普通变量只在函数内部起作用,称为局部变量。当函数执行结束后,局部变量自动删除,不再可以使用。 局部变量的引用比全局变量速度快,应优先考虑使用。 全局变量可以通过关键字global来定义。 这分为两种情况: 一个变量已在函数外定义,如果在函数内需要为这个变量赋值,并要将这个赋值结果反映到函数外,可以在函数内使用global将其声明为全局变量。 如果一个变量在函数外没有定义,在函数内部也可以直接将一个变量定义为全局变量,该函数执行后,将增加一个新的全局变量。 也可以这么理解: 在函数内只引用某个变量的值而没有为其赋新值,如果这样的操作可以执行,那么该变量为(隐式的)全局变量; 如果在函数内任意位置有为变量赋新值的操作,该变量即被认为是(隐式的)局部变量,除非在函数内显式地用关键字global进行声明。 >>> def demo(): global x x = 3 y = 4 print(x,y) >>> x = 5 >>> demo() 3 4 >>> x 3 >>> y NameError: name 'y' is not defined >>> del x >>> x NameError: name 'x' is not defined >>> demo() 3 4 >>> x 3 >>> y NameError: name 'y' is not defined如果局部变量与全局变量具有相同的名字,那么该局部变量会在自己的作用域内隐藏同名的全局变量。 >>> def demo(): x = 3 #创建了局部变量,并自动隐藏了同名的全局变量 >>> x = 5 >>> x 5 >>> demo() >>> x #函数执行不影响外面全局变量的值 5 5. Lambda表达式lambda表达式可以用来声明匿名函数,也就是没有函数名字的临时使用的小函数,尤其适合需要一个函数作为另一个函数参数的场合。也可以定义具名函数。 lambda表达式只可以包含一个表达式,该表达式的计算结果可以看作是函数的返回值,不允许包含复合语句,但在表达式中可以调用其他函数。 >>> f = lambda x, y, z: x+y+z #可以给lambda表达式起名字 >>> f(1,2,3) #像函数一样调用 6 >>> g = lambda x, y=2, z=3: x+y+z #参数默认值 >>> g(1) 6 >>> g(2, z=4, y=5) #关键参数 11 >>> L = [1,2,3,4,5] >>> print(list(map(lambda x: x+10, L))) #模拟向量运算 [11, 12, 13, 14, 15] >>> L [1, 2, 3, 4, 5] >>> data = list(range(20)) #创建列表 >>> data [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] >>> import random >>> random.shuffle(data) #打乱顺序 >>> data [4, 3, 11, 13, 12, 15, 9, 2, 10, 6, 19, 18, 14, 8, 0, 7, 5, 17, 1, 16] >>> data.sort(key=lambda x: x) #和不指定规则效果一样 >>> data [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] >>> data.sort(key=lambda x: len(str(x))) #按转换成字符串以后的长度排序 >>> data [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] >>> data.sort(key=lambda x: len(str(x)), reverse=True) #降序排序 >>> data [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 6. 生成器函数设计要点包含yield语句的函数可以用来创建生成器对象,这样的函数也称生成器函数。 yield语句与return语句的作用相似,都是用来从函数中返回值。与return语句不同的是,return语句一旦执行会立刻结束函数的运行,而每次执行到yield语句并返回一个值之后会暂停或挂起后面代码的执行,下次通过生成器对象的__ next__()方法、内置函数next()、for循环遍历生成器对象元素或其他方式显式“索要”数据时恢复执行。 生成器具有惰性求值的特点,适合大数据处理。 # 编写并使用能够生成斐波那契数列的生成器函数。 >>> def f(): a, b = 1, 1 #序列解包,同时为多个元素赋值 while True: yield a #暂停执行,需要时再产生一个新元素 a, b = b, a+b #序列解包,继续生成新元素 >>> a = f() #创建生成器对象 >>> for i in range(10): #斐波那契数列中前10个元素 print(a.__next__(), end=' ') 1 1 2 3 5 8 13 21 34 55 >>> for i in f(): #斐波那契数列中第一个大于100的元素 if i > 100: print(i, end=' ') break 144 >>> a = f() #创建生成器对象 >>> next(a) #使用内置函数next()获取生成器对象中的元素 1 >>> next(a) #每次索取新元素时,由yield语句生成 1 >>> a.__next__() #也可以调用生成器对象的__next__()方法 2 >>> a.__next__() 3 7. 精彩案例解析编写函数,接收字符串参数,返回一个元组,其中第一个元素为大写字母个数,第二个元素为小写字母个数。 def demo(s): result = [0, 0] for ch in s: if ch.islower(): result[1] += 1 elif ch.isupper(): result[0] += 1 return tuple(result)编写函数,接收一个整数t为参数,打印杨辉三角前t行。 def yanghui(t): print([1]) line = [1, 1] print(line) for i in range(2, t): r = [] for j in range(0, len(line)-1): r.append(line[j]+line[j+1]) line = [1]+r+[1] print(line)编写函数,接收一个正偶数为参数,输出两个素数,并且这两个素数之和等于原来的正偶数。如果存在多组符合条件的素数,则全部输出。 def demo(n): def IsPrime(p): if p == 2: return True if p%2 == 0: return False for i in range(3, int(p**0.5)+1, 2): if p%i==0: return False return True if isinstance(n, int) and n>0 and n%2==0: for i in range(2, n//2+1): if IsPrime(i) and IsPrime(n-i): print(i, '+', n-i, '=', n)编写函数,计算字符串匹配的准确率。 以打字练习程序为例,假设origin为原始内容,userInput为用户输入的内容,下面的代码用来测试用户输入的准确率。 def Rate(origin, userInput): if not (isinstance(origin, str) and isinstance(userInput, str)): print('The two parameters must be strings.') return right = sum((1 for o, u in zip(origin, userInput) if o==u)) return round(right/len(origin), 2)编写函数模拟猜数游戏。系统随机产生一个数,玩家最多可以猜5次,系统会根据玩家的猜测进行提示,玩家则可以根据系统的提示对下一次的猜测进行适当调整。 from random import randint def guess(maxValue=100, maxTimes=5): #随机生成一个整数 value = randint(1,maxValue) for i in range(maxTimes): prompt = 'Start to GUESS:' if i==0 else 'Guess again:' #使用异常处理结构,防止输入不是数字的情况 try: x = int(input(prompt)) except: print('Must input an integer between 1 and ', maxValue) else: #猜对了 if x == value: print('Congratulations!') break elif x > value: print('Too big') else: print('Too little') else: #次数用完还没猜对,游戏结束,提示正确答案 print('Game over. FAIL.') print('The value is ', value) guess()汉诺塔问题基于递归算法的实现 def hannoi(num, src, dst, temp=None): #声明用来记录移动次数的变量为全局变量 global times #确认参数类型和范围 assert type(num) == int, 'num must be integer' assert num > 0, 'num must > 0' #只剩最后或只有一个盘子需要移动,这也是函数递归调用的结束条件 if num == 1: print('The {0} Times move:{1}==>{2}'.format(times, src, dst)) times += 1 else: #递归调用函数自身, #先把除最后一个盘子之外的所有盘子移动到临时柱子上 hannuo(num-1, src, temp, dst) #把最后一个盘子直接移动到目标柱子上 hannuo(1, src, dst) #把除最后一个盘子之外的其他盘子从临时柱子上移动到目标柱子上 hannuo(num-1, temp, dst, src) #用来记录移动次数的变量 times = 1 #A表示最初放置盘子的柱子,C是目标柱子,B是临时柱子 hannoi(3, 'A', 'C', 'B')编写函数,使用算法实现冒泡排序算法 from random import randint def bubbleSort(lst, reverse=False): length = len(lst) for i in range(0, length): flag = False for j in range(0, length-i-1): #比较相邻两个元素大小,并根据需要进行交换,默认升序排序 exp = 'lst[j] > lst[j+1]' #如果reverse=True则降序排序 if reverse: exp = 'lst[j] < lst[j+1]' if eval(exp): lst[j], lst[j+1] = lst[j+1], lst[j] #flag=True表示本次扫描发生过元素交换 flag = True #如果一次扫描结束后,没有发生过元素交换,说明已经按序排列 if not flag: break编写函数,模拟选择法排序 def selectSort(lst, reverse=False): length = len(lst) for i in range(0, length): #假设剩余元素中第一个最小或最大 m = i #扫描剩余元素 for j in range(i+1, length): #如果有更小或更大的,就记录下它的位置 exp = 'lst[j] < lst[m]' if reverse: exp = 'lst[j] > lst[m]' if eval(exp): m = j #如果发现更小或更大的,就交换值 if m!=i: lst[i], lst[m] = lst[m], lst[i]编写函数,模拟二分法查找 def binarySearch(lst, value): start = 0 end = len(lst) while start lst[middle]: start = middle + 1 #在前面一半元素中继续查找 elif value |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |