陈斌老师python课
def merge_sort(lst):
if len(lst) <= 1:
return lst
middle = 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是将其作为一个整体添加上
# 在此只能用extend
return merged
data_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()与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 # 不断更新t
s += 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 = 0
for j in s:
su += int(j)**n
if su == i:
print(i)
解法二:使用函数
def water(n):
a = list(str(n))
m = len(a)
s = 0
for i in a:
s += int(i)**m
return s == n
max_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:
break
else:
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, a
if a % b == 0:
divisor = b
else:
divisor = hcf(b, a % b)
return divisor
num_1 = int(input())
num_2 = int(input())
print(hcf(num_1, num_2))
原理详见:更相减损法为什么可以求出两个数的最大公约数你?数学原理是什么?
def hcf_2(a, b):
if a < b:
a, b = b, a
if a - b == 0:
divisor = a
else:
divisor = hcf_2(b, a-b)
return divisor
num_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 = a
else:
z = b
while True:
if z % a == 0 and z % b == 0:
multiple = z
break
else:
z += 1
return multiple
num_1 = int(input())
num_2 = int(input())
print(lcm(num_1, num_2))
def fact(n):
if n == 1:
s = 1
else:
s = n * fact(n-1)
return s
m = 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 alist
alist = list(map(int, input().split()))
print(bubble_sort(alist))
经过i=0循环,将最大的数排到最后,比较次数为n-1;
i=1循环,将倒第二大的数排到后边,比较次数为n-2;
…
i= n-1循环,比较次数为1
import turtle
def 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 calendar
def month_day(y, m):
if m in [1, 3, 5, 7, 8, 10, 12]:
d = 31
elif m in [4, 6, 9, 11]:
d = 30
else:
if calendar.isleap(y):
d = 29
else:
d = 28
return d
date = 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)
break
n = 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) % a
else:
a_list = (ysf(a-1, b, c-1) + b) % a
return a_list
n = int(input())
m = int(input())
List = []
for i in range(n): # 循环n次后,圆桌的人才能全部出列
List.append(ysf(n, m, i+1)) # i本来从0开始,第一次出列要在原来基础上+1
print(List)