第1关:列表的属性与方法
任务描述
初始化一个空列表,输入一个正整数 n。
接下来,你将被要求输入 n 个指令,每得到一个指令后,根据指令的字符串进行对应的功能操作。
指令形式及对应功能如下:
insert i e: # 在第 i 个位置插入整数 e。
print: # 输出列表
remove e: # 删除第一次出现的整数 e .
append e: # 在列表的末尾插入整数 e.
sort: # 按默认规则排序.
pop: # 弹出列表最后一一个元素
reverse: # 列表元素逆序.
输入格式
第一行输入一个正整数 n
随后的 n 行,每行输入一个如示例格式的命令(或命令加1或2个整数,要求加入列表的必须是整数)
输出格式
每遇到“print”时,在新的一行输出列表
示例 1
- 输入:
12
insert 0 5
insert 1 10
insert 0 6
print
remove 6
append 9
append 1
sort
print
pop
reverse
print
- 输出:
[6, 5, 10]
[1, 5, 9, 10]
[9, 5, 1]
参考代码
l = []
n = int(input())
while n:q = input().split(' ')if q[0] == "insert":l.insert(int(q[1]),int(q[2]))elif q[0] == "remove":l.remove(int(q[1]))elif q[0] == "append":l.append(int(q[1]))elif q[0] == "sort":l.sort()elif q[0] == "pop":l.pop()elif q[0] == "reverse":l.reverse()elif q[0] == "print":print(l)n -= 1
第2关:推导式与生成器
相关知识
推导式可以从一个数据序列构建另一个新的数据序列的结构体。本质上可以将其理解成一种集合了变换和筛选功能的函数,通过这个函数把一个序列转换成另一个序列。
共有三种推导式:
- 列表(list)推导式
- 字典(dict)推导式
- 集合(set)推导式
列表推导式是一种创建新列表的便捷的方式,通常用于根据一个列表中的每个元素通过某种运算或筛选得到另外一系列新数据,创建一个新列表。 列表推导式由1个表达式跟一个或多个for 从句、0个或多个if从句构成。
# 列表推导式由1个表达式跟一个或多个for 从句、0个或多个if从句构成。
# 列表推导式置于一对方括号之中
[x**2 for x in range(10)] #计算range(10)中每个数的平方,推导出新列表
# 得到新列表[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
for前面是一个表达式,in 后面是一个列表或能生成列表的对象。将in后面列表中的每一个数据作为for前面表达式的参数,再将计算得到的序列转成列表。if是一个条件从句,可以根据条件返回新列表。
for前面也可以是一个内置函数或自定义函数,例如:
# 自定义函数f(x)
def fun(x):return x + x ** 2 + x ** 3# 返回 x + x ** 2 + x ** 3
y = [fun(i) for i in range(10)] # 列表推导式,按函数fun(x),推导出新列表
print(y) # 输出列表[0, 3, 14, 39, 84, 155, 258, 399, 584, 819]
列表推导式还可以用条件语句(if从句)对数据进行过滤,用符合特定条件的数据推导出新列表,例如:
def fun(x):return x + x**2 + x ** 3# 返回x + x ** 2 + x ** 3
# 列表推导式,根据原列表中的偶数,推导新列表
y = [fun(i) for i in range(10) if i%2 is 0]
print(y) # 输出列表[0, 14, 84, 258, 584]
可以用多个for从句对多个变量进行计算,例如:
ls = [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
print(ls) # 输出[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
列表推导式应用实例
ls = [-4, -2, 0, 2, 4]
print([x*2 for x in ls])# 将原列表每个数字乘2,推导出新列表 [-8, -4, 0, 4, 8]
print([x for x in ls if x >= 0]) # 过滤列表,返回只包含正数的列表[0, 2, 4]
print([abs(x) for x in ls]) # 应用abs()函数推导新列表[4, 2, 0, 2, 4]
# 调用strip()方法去除每个元素前后的空字符,返回['banana', 'apple', 'pear']
freshfruit = [' banana', ' apple ', 'pear ']
print([fruit.strip() for fruit in freshfruit]) #
# 生成一个每个元素及其平方(number, square)构成的元组组成的列表
print([(x, x**2) for x in range(6)])
# [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
将列俩表推导式的[]改成()即可得到生成器
print([x ** 3 for x in range(10)])
# 输出列表 [0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
print((x ** 3 for x in range(10)))
# 输出生成器对象 <generator object <genexpr> at 0x000001FBC47185C8>
print(list(x ** 3 for x in range(10)))
# 生成器可遍历或转列表
# [0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
字典推导和列表推导的使用方法是类似的,只是中括号该改成大括号。
dic = {'李明': '20191202001', '张凡':'20191202002'} # 姓名:学号
dic_update = {v: k for k, v in dic.items()}
print(dic_update)
# 输出交换了键和值的字典 {'20191202001': '李明', '20191202002': '张凡'}
集合推导式跟列表推导式也是类似的, 唯区别在于它使用大括号{}。
print({x ** 3 for x in range(
10)})
# 输出集合 {0, 1, 64, 512, 8, 343, 216, 729, 27, 125}
实验任务描述
现有一列表 ls = [‘the lord of the rings’,‘anaconda’,‘legally blonde’,‘gone with the wind’],编写程序,实现以下功能:
-
输入“1”,输出元素为0-9的3次方的列表
-
输入“2”,输出元素为0-9中偶数的3次方的列表
-
输入“3”,输出元素为元组的列表,元组中元素依次是0-9中的奇数和该数的3次方
-
输入“4”,将列表 ls 中每个元素首字母转为大写字母,输出新列表
str.capitalize()函数可以将字符串str的首字母转换为大写字母。 -
输入其他字符,输出“结束程序”
拓展实践
在自己电脑上编程,对生成器进行遍历输出,了解生成器成列表推导式的异同。
示例
输入:
1
输出:[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
参考代码
ls = ['the lord of the rings', 'anaconda', 'legally blonde', 'gone with the wind']
s = input()
if s == '1':print([i ** 3 for i in range(10)])
elif s == '2':print([i ** 3 for i in range(10) if i%2 == 0])
elif s == '3':print([(odd, odd**3) for odd in range(10) if odd%2])
elif s == '4':print([i.capitalize() for i in ls])
else:print("结束程序")
第3关:列表的合并与排序
任务描述
读入两行,两行的格式一样,都是用空格分隔的若干个整数,将这些数合并到一个列表中,降序排列后输出整个列表。
提示:
list1 = list(map(int,input().split()))
#读入一行由空格分隔的整数,将其存入list1列表中
输入格式
输入为两行,两行格式一样,都是用空格分隔的若干个整数(整数个数可能为0个)。
输出格式
输出为一行,是元素按数值降序排列后的整数列表。
示例 1
- 输入:
1 5 9 -1 0
234 6 9 2 34 0
- 输出:
[234, 34, 9, 9, 6, 5, 2, 1, 0, 0, -1]
参考代码
l1 = list(map(int, input().split()))
l2 = list(map(int, input().split()))
l1.extend(l2)
l1.sort(reverse=True)
print(l1)
第4关:二维列表排序
任务描述
有以下两个二维列表。
第一个列表的元素是元组,请对其按列表元素的第 2 个元素值从小到大进行排序输出,输出其前 m 项;
列表一:
[('dungeon',7),('winterfell',4),('bran',9),('meelo',6)]
第二个列表的元素仍是列表,请对其分别按每个元素的第 1 和第 3 个元素值从小到大进行排序,输出其前 n 项。
列表二:
[[ 'Angle', '0121701100106',99], [ 'Jack', '0121701100107',86], [ 'Tom', '0121701100109',65], [ 'Smith', '0121701100111', 100], ['Bob', '0121701100115',77], ['Lily', '0121701100117', 59]]
m 和 n 是由用户输入的非负整数,当 m 或 n 大于列表长度时,对整个列表进行排序输出。
输入格式
在两行中分别输入正整数m 和 n
输出格式
列表一排序后的前 m 项
列表二按第 1 个元素值升序排序的前 n 项
列表二按第 3 个元素值升序排序的前 n 项
示例
- 输入:
2
3
- 输出:
[('winterfell', 4), ('meelo', 6)]
[['Angle', '0121701100106', 99], ['Bob', '0121701100115', 77], ['Jack', '0121701100107', 86]]
[['Lily', '0121701100117', 59], ['Tom', '0121701100109', 65], ['Bob', '0121701100115', 77]]
参考代码
l1 = [('dungeon',7),('winterfell',4),('bran',9),('meelo',6)]
l2 = [[ 'Angle', '0121701100106',99], [ 'Jack', '0121701100107',86], [ 'Tom', '0121701100109',65], [ 'Smith', '0121701100111', 100], ['Bob', '0121701100115',77], ['Lily', '0121701100117', 59]]
m = int(input())
n = int(input())
print(sorted(l1, key=lambda x:x[1])[:m])
print(sorted(l2, key=lambda x:x[0])[:n])
print(sorted(l2, key=lambda x:x[2])[:n])
第5关:动物重量排序
任务描述
输入一系列动物名和其重量,重量单位可能是kg,也可能是t,动物名、与重量间空格分隔,重量数值与单位间无分隔。 按重量由小到大排序以二维列表形式输出。
输入格式
每次输入一个动物名,以及其重量和单位,动物名与重量间用空格分隔,直接输入回车时结束输入(此时输入的字符为空字符串)。
提示:判断输入是否为’'空字符串,为True则结束输入。
输出格式
以二维列表形式输出,按重量由小到大升序排序。
示例 1
- 输入:
北极熊 0.75t
企鹅 35kg
海豹 0.35t
海豚 228kg
白鲸 1.35t
- 输出:
[['企鹅', '35kg'], ['海豚', '228kg'], ['海豹', '0.35t'], ['北极熊', '0.75t'], ['白鲸', '1.35t']]
参考代码
def f(x):if 'kg' in x[1]:res = float(x[1][:-2])if 't' in x[1]:res = float(x[1][:-1])res *= 1000return res
l = []
while s :=input().split() :l.append(s)
print(sorted(l, key=f))
第6关:身份证号升位
任务描述
第二代居民身份证是依据2003年6月28日第十届全国人大常委会第3次会议通过的《中华人民共和国居民身份证法》实施的。第一代身份证十五位数升为第二代身份证十八位数的一般规则是:
第一步,在原十五位数身份证的第六位数后面插入19 (1905年1月1日以后出生)或20(2000.1.1-2004.12.31出生),这样身份证号码即为十七位数; 第二步,按照国家规定的统一公式计算出第十八位数,作为校验码放在第二代身份证的尾号。
校验码计算方法:将身份证前十七位数分别乘以不同系数并求和
S = Sum(Ai * Wi)
Ai
:表示第i位置上的身份证号码数字值, i = 0, ... , 16
Wi
:表示第i位置上的加权因子,
Wi
: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
S对11
取模得到余数0-10
,对应的校验码如下:
余数 Y: 0 1 2 3 4 5 6 7 8 9 10
校验码: 1 0 X 9 8 7 6 5 4 3 2
题目假设所有人均出生于1905年1月1日以后,2005年1月1日以前
输入格式
输入一个15位身份证号
输出格式
输出一个18位身份证号
示例 1
-
输入:
310112850409522
-
输出:
310112198504095227
参考代码
old = input()
year = int(old[6:8])
yn = '19' if year>5 else '20'
new = old[:6] + yn + old[6:]
w = [7, 9, 10, 5 , 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
s = 0
for i in range(len(new)):s += int(new[i])*w[i]
mod = s%11
x = '10X98765432'
print(new + x[mod])
第7关:完美立方数
任务描述
费马大定理断言,当整数 n > 2时,关于 a,b,c 的方程 an = b n + cn 没有正整数解。 该定理被提出来后,历经三百多年,经历多人猜想辩证,最终在 1995 年被英国数学家安德鲁.怀尔斯证明。
不过,可以找到大于 1 的 4 个整数满足完美立方等式:
a3 = b3 + c3 + d3
(例如 123 = 63 + 83 + 103)
编写一个程序,对于任意给定的正整数 N(N<=100),寻找所有的四元组(a,b,c,d),满足
a3 = b3 + c3 + d3 (其中 1 < a,b,c,d <=N)
输入格式
整数 N(1 < N <= 100)
输出格式
按照 a 的值从小到大,每行输出一个完美立方等式,其中b,c,d按照非降序排列输出。
(若两个完美立方式中 a 值相同,则 b 值小的先输出;在 b 值相等的情况下,c 值小的先输出,在 b,c 都相等的情况下,d 值小的先输出。)
示例
- 输入:
24
- 输出:
Cube = 6,Triple = (3,4,5)
Cube = 12,Triple = (6,8,10)
Cube = 18,Triple = (2,12,16)
Cube = 18,Triple = (9,12,15)
Cube = 19,Triple = (3,10,18)
Cube = 20,Triple = (7,14,17)
Cube = 24,Triple = (12,16,20)
参考代码
N = int(input())
ls = [i**3 for i in range(1, N+1)]
for a in range(6, N+1):for b in range(2, a):for c in range(b, a):for d in range(c, a):if a**3 == b**3 + c**3 + d**3:print("Cube = {},Triple = ({},{},{})".format(a, b, c, d))
第8关:约瑟夫环问题
任务描述
据说著名历史学家 Josephus有过以下的故事:Josephus及他的朋友共41人围成一个圆圈,由第1个人开始报数,每数到3该人就必须出去,然后再由下一个人重新报数,直到圆圈上少于3人为止。Josephus 将朋友与自己安排在第16个与第31个位置,成为最后剩下的人。
扩展这个问题,当人数为n,每次报数为k时,求解最后的K-1个剩下的人的位置
输入格式
在同一行内输入两个正整数n和k,要求k > = 2且n >= k
输出格式
以列表形式显示剩余的人的序号。
如果k<2或者n<k,打印Data Error!
示例 1
- 输入:
41 3
- 输出:
[16, 31]
参考代码
def josephus(n, k):l = list(range(1, n+1))index = 0while l:temp = l.pop(0)index += 1if index == k:index = 0continuel.append(temp)if len(l)==k-1:print(sorted(l))breakn, k = map(int, input().split())
if k<2 or n<k:print("Data Error!")
else:josephus(n, k)
第9关:统计英文文件中的单词数
任务描述
open(name[, mode[, buffering]])
函数可以打开诸如txt,csv等格式的文件。
如下,定义了read_file()
函数:
def read_file(file):"""接收文件名为参数,读取文件中的数据到字符串中,返回字符串"""with open(file, 'r', encoding='utf-8') as text: # 创建文件对象txt =text.read() # 读文件为字符串return txt # 返回字符串
read_file(file)
可以读取名为file的文件内容,以字符串的形式返回txt,请继续编程统计字符串txt中单词的数量。
提示:统计单词数量时,形如It’s
、Let's
、don't
的缩写形式要按2个单词计数。另外为了处理方便,约定所有测试文件中没有's
表示所有格的情况。
输入格式
输入为一行,是一个文本文件名,如example1.txt
。
输出格式
输出为一行,是对名为example1.txt
的文件内容进行单词数目统计后的结果, 输出共有m个单词
,具体格式见示例。
示例
- 输入:
mySunshine.txt
- 输出:
共有7个单词
参考代码
def read_file(file):"""接收文件名为参数,读取文件中的数据到字符串中,返回这个字符串"""with open(file, 'r', encoding='utf-8') as f:return f.read()def word_list(txt):"""接收字符串为参数,用空格替换字符串中所有标点符号,根据空格将字符串切分为列表返回值为元素为单词的列表"""for c in "!\"'#$%()*+,-.:;<=>?@[\\]^_{|}~/":txt = txt.replace(c,' ')return txt.split()def number_of_words(ls):"""接收一个以单词为元素的列表为参数,返回列表中单词数量,返回值为整型"""return len(ls)if __name__ == '__main__':filename = input() # 读入文件名text = read_file('step10/'+filename) # 读取'step10/'文件夹中用户输入的文件名得到文件内容,存入textwords_list = word_list(text) # 处理text,得到单词的列表words_counts = number_of_words(words_list) #统计单词列表word_list里的单词数print(f'共有{words_counts}个单词')