可变的数据类型:list, dict, set(可修改其中的元素)
不可变的数据类型:str, tuple
重点:str, list, dict
(1).推导式练习
# 利用列表推导式: 找出100以内所有奇数,并将所有奇数乘以3,写入列表。 li = [i * 3 for i in range(1, 101) if i % 2 != 0] print(li) li = [i * 3 for i in range(1, 101, 2)] print(li)
(2).递归的使用:(经典的猴子吃桃)
""" 猴子第一天摘下N个桃子,当时就吃了一半,还不过瘾,就又多吃了一个。 第二天又将剩下的桃子吃掉一半,又多吃了一个。 以后每天都吃前一天剩下的一半零一个。 到第10天在想吃的时候就剩一个桃子了, 问:第一天共摘下来多少个桃子? """ """ 先进行分析: 第n天: 10 9 8 7 剩(个): 1 (1+1)*2=4 (4+1)*2=10 (10+1)*2=22 """ def peachs(n): if n == 10: return 1 else: return (peachs(n + 1) + 1) * 2 print(peachs(1))
没理解递归的话,看下面这个方案:
n = 1 # 天 x = 1 # 桃子几个 while n < 10: # 第9天发现只剩了一个 x = (x + 1) * 2 n += 1 print(x)
(3).基础函数练习1
''' 定义一个函数: 统计传入的字符串里,英文字母、空格、数字和其他字符分别出现次数, 并作为一个字典返回 {'字母': ,'空格': ,'数字': ,'其他字符:' } ''' def count_types(s): # 先定义一个字典 dict = {"字母": 0, "空格": 0, "数字": 0, "其他字符": 0} # 遍历取出字符串中每个值 for i in s: if i.isalpha(): dict["字母"] += 1 # 键值访问,直接自加 elif i.isspace(): dict["空格"] += 1 elif i.isdigit(): dict["数字"] += 1 else: dict["其他字符"] += 1 return dict print(count_types("jing tian 520.1314!"))
(4).基础函数练习2
""" 请定义一个名为titles的函数: 1.接收一句英文(字符串)作为参数 2.将这个英文的每个单词转换成有且只有首字母大写的形式 3.返回转换后的英文句 4.str.title具有这个功能,但在此题不可使用str.title 例如: >>> titles('this is python.') 'This Is Python.' >>> titles('i love python') 'I Love Python' """ # 利用列表推导式+lambda函数 一行代码搞定 # 可读性差,尽量避免写(但我个人比较喜欢这样,感觉眼前一亮,豁然开朗) # 此题逻辑简单,一条语句反而感觉清爽。 s1 = "this is python." s2 = " i love jing tian " g = lambda s: " ".join([i.capitalize() for i in s.split()]) print(g(s1)) print(g(s2))
(5).
""" 给定一个正整数,求出它所有数字的和值。 然后再对这个数,求出它的所有数字的求和。 直到求出的和值是一个个位数为止。 例如 : 16 -> 1 + 6 = 7 942 -> 9 + 4 + 2 = 15 -> 1 + 5 = 6 132189 -> 1 + 3 + 2 + 1 + 8 + 9 = 24 -> 2 + 4 = 6 """ def dr(n): return n % 9 or n and 9 """ 首先 : and > or 当 n!=0 的时候,and是返回右边的值,然后or是返回左边的值 """ print(dr(16)) # 7 print(dr(942)) # 6 print(dr(132189)) # 6
(6).
""" 在金融数据显示的时候,往往看到的是:一个数字,每隔3位用一个逗号隔开。 如: 1234567 -> 1,234,567 1234567890.123 -> 1,234,567,890.123 -614616 -> -614,616 -1234.05 -> -1,234.05 +5201314 -> 5,201,314 """ def main(a, minus=False): """ :param minus: 是否是负数。负数前面的"-"减号就靠它去判断,拼接了 :return: 数字之间都用逗号隔开了 """ # 如果有人多此一举在正数前带了"+"号,不切片的话,后面截取时要出事 if a.find("+") == 0: a = a[1:] # 从后往前,每隔3个字符,切一次。 a_formated = lambda a: ",".join([a[-i:-(i + 3):-1][::-1] for i in range(1, len(a) + 1, 3)][::-1]) # 是否带小数。(isdigit判断的是正整数,如果返回了False,那就是带小数了) if a.isdigit(): if minus: return "{}{}".format("-", a_formated(a)) else: return a_formated(a) else: num_decimal = a[a.find("."):] # 如果是小数,存放小数部分的变量 a = a[:a.find(".")] # 存放真正需要去逗号隔开的部分 if minus: return "{}{}{}".format("-", a_formated(a), num_decimal) else: return "{}{}".format(a_formated(a), num_decimal) if __name__ == '__main__': while 1: a = input("请输入一个数字:") """ 用float()工厂一下,能成功肯定是一个合法的数值。 如果出错了,那就不是一个合法的数值,continue一下让程序回到循环的第一条语句。 不要赋值,不然整数的话就会出现".0"小数。 """ try: float(a) # 先看看能不能转换成float except ValueError: print("输入有误!") continue except TypeError: print("输入有误!") continue except Exception as e: print("未知错误:", e) continue # 是否为负数 if float(a) < 0: g = main(a[1:], minus=True) # 是负数的话,把负号砍了。通过设置布尔值,在函数里返回的时候再进行拼接处理 else: g = main(a) print(g)
更为简介、灵活的方式:
>>> "{:,}".format(18446744073709551615) '18,446,744,073,709,551,615' >>> f"{18446744073709551615:,}" '18,446,744,073,709,551,615'
(7).读取旧文本中的内容。以每10个字为一行,写入新的文本
方案1:(比较笨的方案)
def exchange(old_file, words_number, new_file): """ 读取旧文本中的内容。以每10个字为一行,写入新的文本。 :param old_file: (string)旧的本文名称。路径在打开的时候进行拼接。 :param words_number: (int)指定每几个字为一行。 :param new_file: (string)可以为这个新文本指定自己喜欢的名称。 :return: None """ # 打开原始的文本 with open(old_file + ".txt", "r", encoding="gbk") as f: # 只是打开、读取的用途,不做其他操作。所以是r模式 old_text = f.read() new_text = "" for each in old_text: # 手动替换 : 空格、换行。最后组成一个无空格、无换行的"一行"字符串 new_text += each.replace(" ", "").replace(" ", "").replace(" ", "") # 计算需要截取几次 # 原理在最下 times = int(len(new_text) / words_number) + 1 tmp_li = [] for i in range(times): try: a = new_text[i * words_number:i * words_number + words_number] # 引用 : [原理1] except Exception as e: print("Error at 截取新字符串分片处 :", e) tmp_li.append(a) # 写入新文本 try: with open(new_file + ".txt", "w+") as f: f.writelines(" ".join(tmp_li)) # 手动拼接换行 except Exception as e: print("Error at 写入新文本 : ", e) if __name__ == '__main__': original_file = input("请输入原始文件名:") words_eachline = int(input("每行字数(请输入整数):")) new_file = input("请输入要保存的文件名:") # call function exchange(original_file, words_eachline, new_file) """ 原理1 : # 通过测试下面的代码,可计算出需要如何截取字符 txt = "啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊" ci = int(len(txt) / 10) + 1 print(ci) a = txt[0:10] print(a) a = txt[10:20] print(a) a = txt[20:30] print(a) print("---------------------------") for i in range(ci): a = txt[i * 10:i * 10 + 10] print(a) """
方案2:(我师父给的方案)
n = 10 # 每行字数 with open('old.txt', 'r') as f1, open('new.txt', 'w', encoding='utf-8') as f2: temp = '' for line in f1: temp = temp + line.strip().replace(' ', '') # 去掉两端的回车和空格 while len(temp) >= n: f2.write(temp[:n]) f2.write(' ') temp = temp[10:] f2.write(temp) # 文本最后一行
(8).求s=a+aa+aaa+aaaa+aa..a的值
""" 求s=a+aa+aaa+aaaa+aa..a的值,其中a是一个数字。 例如:2+22+222+2222+22222(此时公有五个数相加),几个数相加由键盘控制 """ def sum_num(num, dig_num): var = 0 for i in range(dig_num): var += int((str(num) * (i + 1))) # 同理 print("3"*3) if i == (dig_num - 1): print(int((str(num) * (i + 1))), end="=") else: print(int((str(num) * (i + 1))), end="+") return var num = int(input("请输入要计算的数字:")) dig_num = int(input("请输入要计算的次数:")) sum_dig = sum_num(num, dig_num) print(sum_dig)
(9).不使用列表的sort方法对列表进行排序
lst = [11, 2, 3, 22, 2, 4, 11, 3] # 方案1. for 循环 lst1 = [] for i in lst: if i not in lst1: lst1.append(i) print(lst1) # 方案2. print(sorted(set(lst), key=lst.index)) # 用集合去重,再按lst原有的顺序去排序
(10).FizzBuzz
""" 写一个程序,打印数字1到100, 3的倍数打印“Fizz”来替换这个数, 5的倍数打印“Buzz”, 对于既是3的倍数又是5的倍数的数字打印“FizzBuzz”。 """ for x in range(1, 101): print("fizz"[x % 3 * len('fizz'):] + "buzz"[x % 5 * len('buzz'):] or x) """ 切片拼接的思路,配合or这个短路关键词。 先以3为例: 3取余3得余数0,余数乘以'fizz'的长度得结果0,得出第一部分的切片值:"fizz"[0:]全部切出来, 3取余5得余数3,余数乘以'buzz'的长度得结果12,得出第二部分的切片值:"buzz"[12:0]什么都切不到,为空字符串,为空字符串, 前后两部分的切片值拼接起来,是'fizz'这个值,是个真值,or的短路特性导致不会再去理会后面的x, 所以遇到3的时候,就是打印出了了"fizz"。 再以5为例: 5取余3得余数2,余数乘以'fizz'的长度得结果8,得出第一部分的切片值:"fizz"[8:]什么都切不到,为空字符串, 5取余5得余数0,0乘以任何数都是为0,得出第二部分的切片值:'buzz'[0:]全部切出来, 前后两部分的切片值拼接起来,是'buzz'这个值,是个真值,再次运用了or的短路特性, 打印出"buzz" 接着以15为例: 15取余3得余数0,0乘以任何数都是为0,得出第一部分的切片值:"fizz"[0:]全部切出来, 15取余5得余数0,0乘以任何数都是为0,得出第二部分的切片值:"buzz"[0:]全部切出来, 前后两部分的切片值拼接起来,是'fizzbuzz'这个值,是个真值,还是运用了or的短路特性, 打印出"fizzbuzz" 最后以1为例: 1取余3得余数1,余数乘以'fizz'的长度得结果4,得出第一部分的切片值:"fizz"[4:]什么都切不到,为空字符串, 1取余5得余数1,余数乘以'buzz'的长度得结果4,得出第二部分的切片值:"buzz"[4:]什么都切不到,为空字符串, 空字符串拼接依然为空,空字符在python中属于条件为假,or就会去找后面的语句,那么就是直接打印出该数本身。 """