R-1.1 编写一个Python函数is_multiple(m,n),用来接收两个整数值n和m,如果n是m的倍数,即存在整数i使得n=mi,那么函数返回True,否则返回false。
def is_multiple(n,m):
return(n%m==0)
>is_multiple(16,4)
>True
>is_multiple(16,3)
>False
R-1.2 编写一个python函数is_even(k),用来接收一个整数K,如果K是偶数返回True,否则返回False。但是在函数中不但能使用乘法、除法或者取余操作。
def is_even(k):
return(k&1==0) #按位与 当k与1全部为1时才取1.
>is_even(-10)
>True
>is_even(5)
>False
R-1.3 编写一个Python函数minmax(data),用来在数的序列中找出最小数和最大数,并以一个长度为2的元组的形式返回,注意:不能通过内置函数min和max来实现。
#解法一:
def minmax(data):
maxx=0
minn=0
for j in range(0,len(data)):
if data[j]>data[maxx]:
maxx=j
if data[j]minmax([2,4,5,6,8,1])
>(8, 1)
#解法二:
def minmax(data):
max=min=data[0]
for val in data:
if valmax:
max=val
return(max,min)
> minmax([2,4,5,6,82,1])
> (82, 1)
R-1.4编写一个Python函数,用来接收正整数 n,返回 1 ~ n 的平方和。
#解法一:
def ji(n):
return (sum(pow(i,2) for i in range(n+1)))
>ji(5)
>55
#解法二:
def sun_square(n):
total=0
for k in range(1,n+1):
total+=k*k
return (total)
>sun_square(5)
>55
R-1.5 基于Python的解析语法和内置函数 sum,写一个单独的命令来计算练习R-1.4中的和。
def sun_square(n):
return(sum(k*k for k in range(1,n+1)))
>sun_square(5)
>55
R-1.6 编写一个Python函数,用来接收正整数n,并返回 1 ~ n 中所有的奇数的平方和。
def sum_ord_square(n):
total=0
for k in range(1,n+1,2):
total+=k*k
return(total)
>sum_ord_square(10)
>165
R-1.7 基于Python的解析语法和内置函数 sum,写一个单独的命令来计算练习R-1.6中的和。
def sum_or_square(n):
return(sum(k*k for k in range(1,n+1,2)))
>sum_or_square(10)
>165
R-1.8 Python 允许负整数作为序列的索引值,如一个长度为 n 的字符串 s,当索引值 -n <= k < 0 时,所指的元素为 s[k],那么求一个正整数索引值 j >= 0,使得 s[j] 指向的也是相同的元素。
n=9
k=-3
data=[1,2,3,3,4,5,6,8,9]
print(data[k])
j=n+k
print(data[j])
>6
>6
R-1.9 要生成一个值为 50, 60, 70, 80 的排列,求 range构造函数的参数.
for i in range(50,82,10):
print(i,end=' ') #end=' '表示每个输出用空格来隔开
>50 60 70 80
R-1.10 要生成一个值为 8, 6, 4, 2, 0, -2, -4, -6, -8 的排列,求 range 构造函数中的参数。
for i in range(8,-10,-2):
print(i,end=' ')
>8 6 4 2 0 -2 -4 -6 -8
R-1.11演示怎样使用 Python 列表解析语法来产生列表 [1, 2, 4, 8, 16, 32, 64, 128, 256].
list(2**k for k in range(9))
>[1, 2, 4, 8, 16, 32, 64, 128, 256]
list(map((lambda x: 2 ** x), range(9)))
>[1, 2, 4, 8, 16, 32, 64, 128, 256]
R-1.12 Python 的 random 模块包括一个函数 choice(data),可以从一个非空序列返回一个随机元素。Random模块还包含一个更基本的 randrange 函数,参数化类似于内置的 range 函数,可以在给定范围内返回一个随机数。只使用 randrange 函数,实现自己的 choice 函数。
def mychoice(data):
import random
return data[random.randrange(len(data))]
>data=[1,2,3,8]
>mychoice(data)
>2
R-1.13 编写一个函数的伪代码描述,该函数用来逆置 n 个整数的列表,使这些以相反的顺序输出,并将该方法与可以实现相同功能的 Python 函数进行比较。
def myReverse(data):
return data[::-1]
>data=[1,4,5,7,3,0]
>myReverse(data)
>[0, 3, 7, 5, 4, 1]
lista = [1, 2, 3, 4]
lista.reverse()
print(lista)
>[4, 3, 2, 1]
l=[22,45,26,34,56,78]
for i in reversed(l):
print(i,end=' ')
>78 56 34 26 45 22
R-1.14 编写一个 Python 函数,用来接收一个整数序列,并判断该序列中是否存在一对乘积是奇数的互不相同的数
#解法一:
def productIsOdd(lst):
lst=[i for i in lst if i%2>0]
if len(set(lst))>=2:
return True
else:
return False
>lst=[2,3,3,4,5]
>productIsOdd(lst)
>True
#解法二:
def hasOddMut1(data):
temp = []
for item in data:
if item % 2 != 0 and item not in temp:
temp.append(item)
if len(temp) >= 2:
return True
else:
return False
#解法三
def hasOddMut2(data):
temp = set() #set确保列表的元素各不相同
for item in data:
if item % 2 != 0:
temp.add(item)
return (len(temp) >= 2)
>data = [1, 2, 4, 6, 8, 3]
>hasOddMut2(data)
>True
R-1.15 编写一个 Python 函数,用来接收一个数字序列,并判断是否所有数字都互不相同
def notsame(lis):
for i in range(len(lis)):
for j in range(i):
if lis[j]==lis[i]:
return False
return True
>lis=[1,2,3,45,6]
>notsame(lis)
>True
#解法二:
def isDiff1(data):
temp = set()
for item in data:
if item not in temp:
temp.add(item)
else:
return False
return True
#解法三:高效利用set
def isDiff2(data):
return (len(data) == len(set(data)))
R-1.17 1.5.1节 scale 函数的实现如下。它能正常工作吗?请给出原因。
def scale(data, factor):
for val in data:
val = val * factor
it can’t work.val只是对data列表中数据的引用,是一个变量,而不是列表元素对象本身。需要在对象上改变,需要采用索引的方法
R-1.18 演示如何使用 Python 列表解析语法来产生列表 [0, 2, 6, 12, 20, 30, 42, 56, 72, 90]。
lis=[i*(i+1) for i in range(10)]
print(list)
>[0, 2, 6, 12, 20, 30, 42, 56, 72, 90]
R-1.19 演示如何使用 Python 列表解析语法在不输入所有 26 个英文字母的情况下产生列表 [‘a’, ‘b’, ‘c’,…, ‘z’]。
lis=[chr(ord('a')+i) for i in range(26)]
print(lis,end=' ')
>['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
R-1.20 Python 的 random 模块包括一个函数 shuffle(data),它可以接受一个元素的列表和一个随机的重新排列元素,以使每个可能的序列发生概率相等。 random 模块还包括一个更基本的函数 randint(a, b),它可以返回一个 a 到 b (包括两个端点)的随机整数。只使用 randint 函数,实现自己的 shuffle 函数。
def myshuffle(lis):
import random
lislen=len(lis) #lis的长度
shuffle=[] #定义一个空列表
lis2=list(range(len(lis))) #用lis的长度来range一个列表,复制给lis2
while lis2:
i=random.randint(0,lislen-1) #i 取值为0-(lis-1)长度的随机值
if i in lis2:
shuffle.append(lis[i]) #从shuffle列表中添加 lis[i]元素
lis2.remove(i) #将i 元素从lis2中去除
lis[:]=shuffle[:] #直到lis列表等于shuffle列表相等时 跳出循环
R-1.21 编写一个Python程序,反复从标准输入读取一行直到抛出 EOFError 异常,然后以相反的顺序输出这些行(用户可以通过键按 Ctrl + D 结束输入)。
def func():
ls=[]
while True:
try:
line=input()
l=list(map(int,line.split()))
ls=l[::-1]
print(ls)
except ValueError:
print("错误")
func()
>1 2 3
>[3, 2, 1]
>sad d a
>错误
R-1.22 编写一个Python程序,用来接收长度为 n 的两个整型数组 a 和 b 并返回数组 a 和 b 的点积。也就是返回一个长度为 n 的数组 c,即 c[i] = a[i] ⋅⋅ \cdot⋅ b[i], for i = 0, …, n-1.
#解法一:
def ab(a,b):
c=[a[i]*b[i] for i in range(0,len(a))]
return c
>a=[1,2,3]
>b=[2,3,4]
>ab(a,b)
>[2, 6, 12]
#解法二:
def ab2(a,b):
import numpy as np
return np.array(a)*np.array(b)
>a=[1,2,3]
>b=[2,3,4]
>ab2(a,b)
>array([ 2, 6, 12])
R-1.23 给出一个 Python 代码片段的例子,编写一个索引可能越界的元素列表。如果索引越界,程序应该捕获异常结果并打印以下错误消息:“Don’t try buffer overflow attacks in Python!”
def function(data,i):
try:
return data[i]
except IndexError:
print("Don't try buffer overflow attacks in Python!")
>data=[2,35,4]
>function(data,2)
>4
>function(data,6)
>Don't try buffer overflow attacks in Python!
R-1.24 编写一个 Python 函数,计算所给字符串中元音字母的个数
def numberOFvowels(s):
vowels=['a','e','i','o','u','A','E','I','O','U']
compte=[]
for i in s:
if i in vowels:
compte.append(i)
return len(compte)
>s=['s','a','f','e','u']
>numberOFvowels(s)
>3
def num_vowels(tex):
total=0
for i in tex.lower():
if i in 'aeiou':
total+=1
return tota
>tex='AEiyrho'
>num_vowels(tex)
>4
R-1.25 编写一个 Python函数,接收一个表示一个句子的字符串 s,然后返回该字符串的删除了所有标点符号的副本。例如, 给定字符串 “Let’s try, Mike.”,这个函数将返回 “Lets try Mike”。
def removePunctuation(s):
import string
punctuation=string.punctuation #punctuation调用string中的字符串,赋值给punctuation
s2=''
for i in s:
if i not in punctuation:
s2+=i
return s2
>s='djas*dsa$ldas w #kfja'
>removePunctuation(s)
>'djasdsaldas w kfja'
R-1.26 编写一个程序,需要从控制台输入 3 个整数 a、b、c,并确定它们是否可以在一个正确的算术公式(在给定的顺序)下成立,如“a + b = c” “a = b - c” 或 “a * b = c”。
def function():
a=int(input('a:'))
b=int(input('b:'))
c=int(input('c:'))
if (a+b==c) or (a==b-c) or (a*b==c):
return True
else:
return False
>function()
>a:1
>b:2
>c:5
>False
R-1.27 在 1.8 节中,我们对于计算所给整数的因子时提供了 3 种不同的生成器的实现方法。 1.8 节末尾处的第三种方法是最有效的,但我们注意到,它没有按递增顺序来产生因子。修改生成器,使得其按递增顺序来产生因子,同时保持其性能优势。
def factors(n):
k = 1
temp = []
while k * k < n:
if n % k == 0:
yield k
temp.append(n // k)
k += 1
if k * k == n:
yield k
for item in temp[::-1]:
yield item
>list(factors(100))
>[1, 2, 4, 5, 10, 20, 25, 50, 100]
R-1.28 在 n 维空间定义一个向量 v=(v1,v2,…,vn) v=(v1,v2,…,vn) 的 p 范数, 如下所示:
||v||=(v1P+V2P+…VnP)(1/p)
对于 p = 2 的特殊情况,这就成了传统的欧几里得范数,表示向量的长度。例如,一个二维向量坐标为 (4,3) 的欧几里得范数为(42+32)(1/2)=(16+9)(1/2)=25**(1/2).编写 norm 函数,即 norm(v, p),返回向量 v 的 p 范数的值, norm(v),返回向量 v 的欧几里得范数。你可以假定 v 是一个数字列表。
def norm(v,p=2):
sum=0
for i in v:
sum=sum+pow(i,p)
return pow(sum,1.0/p)
>norm((4,3))
>5.0
R-1.29 编写一个 Python 程序,输出由字母 ‘c’,‘a’,‘t’,‘d’,‘o’,‘g’ 组成的所有可能的字符串(每个字母只使用1次)
import itertools #itertools无限迭代器
x=itertools.permutations(['a','c','t','d','o','g'],6) #permutations全排列
print(list(map(''.join,x)))
def allStr():
s=['c','a','t','d','o','g']
for i in s:
#print(i)
ss=s.copy()
ss.remove(i)
for j in ss:
#print(i+j)
sss=ss.copy()
sss.remove(j)
for k in sss:
#print(i+j+k)
ssss=sss.copy()
ssss.remove(k)
for m in ssss:
#print(i+j+k+m)
sssss=ssss.copy()
sssss.remove(m)
for n in sssss:
#print(i+j+k+m+n)
ssssss=sssss.copy()
ssssss.remove(n)
for p in ssssss:
print(i+j+k+m+n+p)
R-1.30 编写一个 Python 程序,输入一个大于 2 的正整数,求将该数反复被 2 整除直到商小于 2 为止的次数
def isdivid():
a=int(input('a:'))
num=0
while a>=2:
a=int(a/2)
num+=1
return num
>isdivid()
>a:33
>5
R-1.31 编写一个可以“找零钱”的 Python 程序。程序应该将两个数字作为输入,一个是需要支付的钱数,另一个是你给的钱数。当你需要支付的和所给的钱数不同时,它应该返回所找的纸币和硬币的数量。纸币和硬币的值可以基于之前或现在政府的货币体系。试设计程序,以便返回尽可能少的纸币和硬币。
def cahngenote():
youpay=int(input("你所付的钱:\n"))
shouldpay=int(input("应该付的钱:\n"))
if youpay>shouldpay:
givechange=int(youpay-shouldpay)
if givechange<5:
purse=givechange
print("找零:", purse)
if givechange>5:
purse1=givechange-5
purse2=purse1
print("找零:","5","和",purse2)
def makeChange(changed,given):
coin=[100,50,20,10,5,1,0.5,0.1]
change=given-changed
if change==0:
return
i=0
ok=True
while ok:
if coin[i]<=change:
print("面值"+str(coin[i])+"张数"+str(change//coin[i]))
ok=False
makeChange(0,change%coin[i])
i+=1
> makeChange(33,100)
> 面值50张数1
面值10张数1
面值5张数1
面值1张数2
def function():
coins={'0.5':0,'1':0,'5':0, '10':0, '20':0, '50':0, '100':0}
temp=input("输入应付的钱和总的钱:\n").split(" ")
pay,total=int(temp[0]),int(temp[1])
rest=total-pay
coins[100]=int(rest/100)
rest = int(rest % 100)
coins[50] = int(rest / 50)
rest = int(rest % 50)
coins[20] = int(rest / 20)
rest = int(rest % 20)
coins[10] = int(rest / 10)
rest = int(rest % 10)
coins[5] = int(rest / 5)
rest = int(rest % 5)
coins[1] = int(rest / 1)
rest = int(rest % 1)
coins[0.5] = int(rest / 0.5)
rest = int(rest % 0.5)
return coins.values()
>function()
>输入应付的钱和总的钱:32 56
>dict_values([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 0])
R-1.32 编写一个 Python 程序来模拟一个简单的计算器,使用控制台作为输入和输出的专用设备。也就是说,计算器的每一次输入做一个单独的行,它可以输入一个数字(如1034或12.34)或操作符(如 + 或 = )。每一次输入后,应该输出计算器显示的结果并将其输出到 Python 控制台。
def function32():
temp = input("Please input Number1 Operation Number2: \n").split(" ")
num1 = int(temp[0])
num2 = int(temp[2])
oper = str(temp[1])
if oper == '+':
result = num1 + num2
elif oper == '-':
result = num1 - num2
elif oper == '*':
result = num1 * num2
elif oper == '/':
result = num1 / num2
else:
raise EOFError("Error Input!")
return result
>function32()
>Please input Number1 Operation Number2: 8 * 8
>64
R-1.34 一种惩罚学生的常见方法是让他们将一个句子重复写很多次。编写独立的 Python 程序,将以下句子 “I will never spam my friends again.” 写 100 次。程序应该对句子进行计数,另外,应该有 8 次不同的随机输入错误。
from random import choices,choice
from time import sleep
def get_space_index(sample):
sample=list(sample) #sample转换成list列表
space_index_list=[] #定义一个空列表
while ' ' in sample: #当sample中有空格时
index=sample.index(' ') #将sample空格的索引赋值给index
space_index_list.append(index+len(space_index_list)) #在space_index_list 列表中添加索引和长度
sample.pop(index)
return space_index_list
def punish_write():
sample=list(" I will never spam my friends again.")
cnt=0
wrong_cnt=8
wrong_index_list=choices(list(range(100)),k=8)#拼写错误的索引组成的列表
print(wrong_index_list)
space_index_list=get_space_index(sample) #调用上述定义的函数,创造sample中含有的空格的索引列表
wrong_times=0 #错误0次
while cnt<100:
if cnt in wrong_index_list:#如果当前的索引在错误列表索引中
wrong_times+=1
while True:
wrong=choice(range(len(sample)))#选择在sample列表的任意一部分出错的索引,并将之赋值给wrong
if wrong not in space_index_list:#如果出现错误的地方不在空格列表中
sample[wrong]=choice([chr(i) for i in range(65,65+26)]+[chr(i) for i in range(97,97+26)]+[',','.'])#错误出现在字母拼写中
break
for i in sample:
print(i,end='')
sleep(0.05)
print(' |{:3d}| \twrong {}'.format(cnt+1,wrong_times),end='\n')
sleep(0.1)
else:
for i in sample:
print(i,end='')
sleep(0.03)
print('|{:3d}|'.format(cnt+1),end='\n')
sleep(0.1)
cnt+=1
sample=list(" I will never spam my friends again.")
R-1.35 生日悖论是说,当房间中人数 n 超过 23 时,那么该房间里有两个人生日相同的可能性是一半以上。这其实不是一个悖论,但许多人觉得不可思议。设计一个 Python 程序,可以通过一系列随机生成的生日的实验来测试这个悖论,例如可以 n = 5, 10, 15, 20, …, 100 测试这个悖论。
def function(num):
import math
from decimal import Decimal
prop=1-Decimal((math.factorial(365)))/Decimal(math.pow(365,num)*math.factorial(364-num))
return prop
def functions(num):
import math
prop=1-math.pow((364/365),(num*(num-1)/2))
return prop
>functions(32)
>0.7435365267749252
R-1.36 编写一个 Python程序,输入一个由空格分隔的单词列表,并输出列表中的每个单词出现的次数。在这一点上,你不需要担心效率,因为这个问题会在本书后面的部分予以解决。
def function1():
import string
temp=input("输出一行字符:\n").strip(string.punctuation).split(" ")
keys=list(set(temp))
result=dict(zip(keys,[0]*len(keys)))
for item in temp:
result[item]+=1
return result
>function1()
>输出一行字符: "w jj w "
>{'w': 2, '': 1, 'jj': 1}