本文主要是介绍[Python] 慕课北京大学陈斌老师Python基础课2-7章 学习笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
慕课北京大学陈斌老师python课 学习笔记
- 数据类型
- 列表归并排序
- 字符串操作
- ls.reverse()与reversed(ls)区别
- 列表元素绝对值排序
- 计算与控制流
- 阶乘求和
- 英文对应阿拉伯数字
- 水仙花数
- 打印完数
- 打印素数
- 最大公约数和最小公倍数
- 辗转相除法
- 辗转相减法
- 求阶乘
- 冒泡排序
- 基本扩展模块
- 分形数
- 判断第几天
- 特殊的数
- 大大的叉
- 约瑟夫环问题
个人学习记录,如有错误欢迎指正。
数据类型
陈斌老师python课
列表归并排序
def merge_sort(lst):if len(lst) <= 1:return lstmiddle = int(len(lst) / 2)left = merge_sort(lst[:middle])right = merge_sort(lst[middle:])merged = []while left and right:merged.append(left.pop(0) if left[0] <= right[0] else right.pop(0))# left.pop(0)是提取left的第0个元素并更新left# 将left与right中第0位上最小的元素提取出来加到merged中# 若right的更小,则right的第0位被提取,下一次比较的是right的第1位和left的第0位merged.extend(left if left else right)# extend与append都是将元素添加到merged中,添加一个元素无差别# 若添加的为列表或元组,extend是添加列表的元素,而append是将其作为一个整体添加上# 在此只能用extendreturn mergeddata_lst = [6, 202, 100, 301, 38, 8, 1]
print(merge_sort(data_lst))
字符串操作
s = ‘abcdefg123456’
要获得 ‘54321’
s[::-1][0:5] # 先反转载取5个字符
s[-1:6:-1]
s[-1:-6:-1] # 6和-6都是g,不包含g
# 步长为-1时,是从右向左取
# 故s[0:5:-1]的结果为'’(空字符串)因为它根本就没切到字符
ls.reverse()与reversed(ls)区别
-
ls.reverse()与ls.sort() 无返回值,直接改变原列表
若print(ls.reverse()) 返回 None
可以先ls.reverse() 再 print(ls) -
reversed()与sorted()不改变原列表,有返回值
reversed()返回一个反转的迭代器,不是列表
sorted()返回列表
列表元素绝对值排序
输入一个列表,要求列表中的每个元素都为整数;
将列表中的所有元素按照它们的绝对值大小进行排序,绝对值相同的还保持原来的相对位置,打印排序后的列表(绝对值大小仅作为排序依据,打印出的列表中元素仍为原列表中的元素).
输入:-2 1 3
输出:[1, -2, 3]
a_list = list(map(int, input().split()))
print(sorted(a_list, key=abs))
计算与控制流
阶乘求和
给定任意正整数n,计算 1 ! + 2 ! + 3 ! + . . . + n ! 1!+2!+3!+...+n! 1!+2!+3!+...+n!的值。
解法有很多,可参考Python花式编程:6种方法计算1!+2!+…+n!.
在此列举两个:
n = int(input())
t, s = 1, 0
for i in range(1, n+1):t = t*i # 不断更新ts += t # 下个数的阶乘只需要在上个t的基础上再乘以此数即可
print(s)
此方法时间最少。
还可使用math库中求阶乘的函数factorial.
from math import factorial
n = int(input())
s = sum(map(factorial, range(1, n+1)))
print(s)
英文对应阿拉伯数字
给定一个英文数字字符串,打印相应阿拉伯数字字符串。
输入:one-four-five-nine
输出:1459
str = input().split('-')
d = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5,\'six': 6, 'seven': 7, 'eight': 8, 'nine': 9, 'ten': 10, 'zero': 0}
for i in str:print(d.get(i), end='')
水仙花数
水仙花数是指一个n位数 (n≥3),它的每个位上的数字的n次幂之和等于它本身。
例如:153是一个“水仙花数”,因为 153 是个3位数,而 1 3 + 5 3 + 3 3 = 153 1^3+5^3+3^3=153 13+53+33=153。
输入一个正整数max,输出100到max之间的所有水仙花数(包括max)
输入:2500
输出:
153
370
371
407
1634
m = input()
for i in range(100, int(m)+1):s = list(str(i))n = len(s)su = 0for j in s:su += int(j)**nif su == i:print(i)
解法二:使用函数
def water(n):a = list(str(n))m = len(a)s = 0for i in a:s += int(i)**mreturn s == nmax_n = int(input())
for j in range(100, max_n+1):if water(j):print(j)
打印完数
一个数如果恰好等于它的因子之和,这个数就称为"完数"。例如 6 = 1+2+3.
输入一个正整数n(n<1000),输出1到n之间的所有完数(包括n)。
输入:30
输出:
6
28
n = int(input())
for i in range(1, n+1):s = []for j in range(1, i):if i % j == 0:s.append(j) # 将其因子放在列表内if sum(s) == i:print(i)
打印素数
给定一个大于2的正整数n,打印出小于n(不包括n且n不大于100)的所有素数。
要求将符合条件的输出填入一个列表中,打印的结果为该列表。
输入:10
输出:[2, 3, 5, 7]
若一个数为合数,则它可分解为两个比自身小的数的乘积,其中一个比它的开方大,一个小。所以在进行第二次遍历的时候只要看小于开方的情况即可。
n = int(input())
s = []
for i in range(2, n):for j in range(2, int(i**0.5)+1):if i % j == 0:breakelse:s.append(i)
print(s)
补充:
for…else与 while…else
for <循环变量> in <可迭代对象>:<语句块1>break # 跳出循环continue # 略过余下循环语句,再执行
else: # 迭代完毕,则执行<语句块2>while <逻辑表达式>:<语句块>break # 跳出循环continue # 略过余下循环语句<语句块>
else: # 条件不满足退出循环,则执行<语句块>
最大公约数和最小公倍数
求最大公约数可用辗转相除法和辗转相减法
辗转相除法
原理详见:欧几里德算法
def hcf(a, b):if a < b:a, b = b, aif a % b == 0:divisor = belse:divisor = hcf(b, a % b)return divisornum_1 = int(input())
num_2 = int(input())
print(hcf(num_1, num_2))
辗转相减法
原理详见:更相减损法为什么可以求出两个数的最大公约数你?数学原理是什么?
def hcf_2(a, b):if a < b:a, b = b, aif a - b == 0:divisor = aelse:divisor = hcf_2(b, a-b)return divisornum_1 = int(input())
num_2 = int(input())
print(hcf_2(num_1, num_2))
最小公倍数=两数乘积/最大公约数
在上面程序的后边加上
multiple = num_1 * num_2 / hcf_2(num_1, num_2)
print(multiple)
或者使用原始的方法:
取出两个整数中的较大者,然后将这个数依次去除原先的两个数,如果可以整除就是最小公倍数。如果不可以,则依次加1,直至可以被两个数整除为止。
def lcm(a, b):if a < b:z = aelse:z = bwhile True:if z % a == 0 and z % b == 0:multiple = zbreakelse:z += 1return multiplenum_1 = int(input())
num_2 = int(input())
print(lcm(num_1, num_2))
求阶乘
def fact(n):if n == 1:s = 1else:s = n * fact(n-1)return sm = int(input(""))
print(fact(m))
冒泡排序
冒泡排序是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
已知输入为一个列表,列表中的元素都为整数,我们定义冒泡排序函数为bubbleSort,将列表中的元素按从小到大进行排序后得到一个新的列表并输出
def bubble_sort(alist):n = len(alist)for i in range(n):for j in range(n - i - 1):if alist[j] > alist[j+1]:alist[j], alist[j+1] = alist[j+1], alist[j]return alistalist = list(map(int, input().split()))
print(bubble_sort(alist))
经过i=0循环,将最大的数排到最后,比较次数为n-1;
i=1循环,将倒第二大的数排到后边,比较次数为n-2;
…
i= n-1循环,比较次数为1
基本扩展模块
分形数
import turtledef tree(branch_len, t):if branch_len > 5:t.forward(branch_len)t.right(20)tree(branch_len-15, t) # 画右边的树枝t.left(40)tree(branch_len-15, t) # 画左边的树枝t.right(20)t.backward(branch_len) # 回到原处def main():t = turtle.Turtle() # 生成海龟my_win = turtle.Screen() # 生成画布t.left(90)t.up()t.backward(100)t.down() # 海龟调整位置t.color('green')tree(45, t)my_win.exitonclick() # 点击关闭图形窗口,避免绘制完直接关闭main()
绘制tree(15,t)时,在终点左右转动但是没有前进,最后执行t.backward(branch_len)回到上一个节点。
判断第几天
给定年月日,如2019/1/8,打印输出这一天是该年的第几天。
输入:2019/1/8
输出:8
解法一:笨办法,自己做的
import calendardef month_day(y, m):if m in [1, 3, 5, 7, 8, 10, 12]:d = 31elif m in [4, 6, 9, 11]:d = 30else:if calendar.isleap(y):d = 29else:d = 28return ddate = list(map(int, input().split('/')))
n = 0
for i in range(1, date[1]):n += month_day(date[0], i)
print(n+date[2])
解法二:网上搜的简单
from datetime import *
d = input()
d1 = datetime.strptime(d[:4]+'/1/1', '%Y/%m/%d') # 这一年的1月1号
d2 = datetime.strptime(d, '%Y/%m/%d') # 输入的日期
print((d2-d1).days+1) #.days只显示天数,否则后边还有时间
特殊的数
一个特殊的正整数,它加上150后是一个完全平方数,再加上136又是一个完全平方数,求符合条件的最小的一个数。
思路:如果一个数的平方根的平方等于该数,这说明此数是完全平方数;若一个数不是完全平方数,则它开方后为小数,取整后再平方不等于原本的值
n = 1
while 1:if int((n+150)**0.5)**2 == (n+150) and int((n+150+136)**0.5)**2 == (n+150+136):print(n)breakn = n + 1
大大的叉
打印出n阶的“叉”,这个叉图案由字符‘+’和‘X’构成,n越大,这个图案也就越大
输入:3
输出:
X+++X
+X+X+
++X++
+X+X+
X+++X
n = int(input())
for i in range(2*n-1):for j in range(2*n-1):if j == i or j == 2*n-1-i-1:print('X', end='')else:print('+', end='')print()
解法二:
n = int(input())
for i in range(2 * n - 1):l = (2 * n - 1) * ['+']l[i] = 'X'l[-1-i] = 'X'print("".join(l)) # 将列表转换为字符串# str.join(iter)是在iter变量中出最后一个元素外每个元素后增加一个str
约瑟夫环问题
已知n个人(以编号0,1,2,3…n-1分别表示)围坐在一张圆桌周围。从编号为0的人开始报数1,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
输入:两个正整数n, m,其中3<=n<=100, 1<=m<=n
输出:按照顺序出列的人的编号列表
思路:详细请见约瑟夫环问题递归解法的一点理解.
代码是按照思路自己改的,有错误欢迎指正
def ysf(a, b, c): # a为总人数,b为最大报到数,c为第c次出列if c == 1:a_list = (a + b - 1) % aelse:a_list = (ysf(a-1, b, c-1) + b) % areturn a_listn = int(input())
m = int(input())
List = []
for i in range(n): # 循环n次后,圆桌的人才能全部出列List.append(ysf(n, m, i+1)) # i本来从0开始,第一次出列要在原来基础上+1
print(List)
这篇关于[Python] 慕课北京大学陈斌老师Python基础课2-7章 学习笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!