python第三章——选择和循环

例3-2:用户输入若干个分数,求所有分数的平均分。每输入一个分数后询问是否继续输入下一个分数,回答“yes”就继续输入下一个分数,回答“no”就停止输入分数。

numbers=[]
while True:
    x=input('请输入一个成绩:')
    try:
        numbers.append(float(x))
    except:
        print('不是合法成绩')
    while True:
        flag=input('继续输入吗? (yes/no)')
        if flag.lower() not in ('yes','no'): # 限定用户输入内容必须为yes或no
            print('只能输入yes或no')
        else:
            break
    if flag.lower()=='no':
            break
    print(sum(numbers)/len(numbers))

例3-3:编写程序,判断今天是今年的第几天。

import time
date=time.localtime()
year,month,day=date[:3]
day_month=[31,28,31,30,31,30,31,31,30,31,30,31]

if year%400==0 or (year%4==0 and year%100!=0): #判断是否为闰年
    day_month[1]=29
if month==1:
    print(day)
else:
    print(sum(day_month[:month-1])+day)

其中闰年判断可以直接使用calendar模块的方法。

>>> calendar.isleap(2016) True

>>> calendar.isleap(2015) False

或者使用下面的方法直接计算今天是今年的第几天

>>> datetime.date.today().timetuple().tm_yday   208

>>> datetime.date(2015,7,25).timetuple().tm_yday   206

也可以使用datetime模块提供的功能来计算

>>> today = datetime.date.today()

>>> today   

datetime.date(2015, 7, 27)

>>> firstDay = datetime.date(today.year,1,1)

>>> firstDay

datetime.date(2015, 1, 1)

>>> daysDelta = today-firstDay+datetime.timedelta(days=1)

>>> daysDelta.days     

208

例3-4:计算1+2+3+…+100 的值。

s=0
for i in range(1,101):
    s=s+i
print(s)
print(sum(range(1,101)))

5050
5050

例3-5:输出序列中的元素。

a_list=['a','b','mpilgrim','z','exemple']
for i,v in enumerate(a_list):
    print('列表的第',i+1,'个元素是:',v)

列表的第 1 个元素是: a
列表的第 2 个元素是: b
列表的第 3 个元素是: mpilgrim
列表的第 4 个元素是: z
列表的第 5 个元素是: exemple

例3-6:求1~100之间能被7整除,但不能同时被5整除的所有整数 。

for i in range(1,101):
    if i%7==0 and i%5!=0:
        print(i)

7
14
21
28
42
49
56
63
77
84
91
98

例3-7:输出“水仙花数”。所谓水仙花数是指1个3位的十进制数,其各位数字的立方和等于该数本身。例如:153是水仙花数,因为153 = 13 + 53 + 33 。

for i in range(100,1000):
    #这里是序列解包的用法
    bai,shi,ge=map(int,str(i))
    if ge**3+shi**3+bai**3==i:
        print(i)

153
370
371
407

例3-8:求平均分。

score=[70,90,78,85,97,94,65,80]
s=0
for i in score:
    s+=i;
print(s/len(score))
print(sum(score)/len(score))  #可以直接这么做

82.375
82.375

例3-9:打印九九乘法表。

for i in range(1,10):
    for j in range(1,i+1):
        print('{0}*{1}={2}'.format(i,j,i*j).ljust(6),end=' ')
    print()

1*1=1  
2*1=2  2*2=4  
3*1=3  3*2=6  3*3=9  
4*1=4  4*2=8  4*3=12 4*4=16 
5*1=5  5*2=10 5*3=15 5*4=20 5*5=25 
6*1=6  6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 
7*1=7  7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 
8*1=8  8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 
9*1=9  9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81 

例3-10:求200以内能被17整除的最大正整数。

for i in range(200,0,-1):
    if i%17==0:
        print(i)
        break

187

例3-11:判断一个数是否为素数。

import math

n=input('Input an inter:')
n=int(n)
m=math.ceil(math.sqrt(n)+1)
for i in range(2,m):
    if n%i==0 and i<n:
        print('No')
        break
else:
    print('Yes')

例3-12:鸡兔同笼问题。假设共有鸡、兔30只,脚90只,求鸡、兔各有多少只。

for ji in range(0,31):
    if 2*ji+(30-ji)*4==90:
        print('ji:',ji,'tu:',30-ji)

ji: 15 tu: 15

另解

def demo(tui,jitu):
    tu=(tui-jitu*2)/2
    if int(tu)==tu:
        return (int(tu),int(jitu-tu))
    else:
        return 'Data Error'

print(demo(90,30))

例3-13:编写程序,输出由1、2、3、4这四个数字组成的每位数都不相同的所有三位数。


digits=(1,2,3,4)
for i in digits:
    for j in digits:
        for k in digits:
            if i!=j and j!=k and j!=k:
                print(i*100+j*10+k)

121
123
124
131
132
134
141
142
143
212
213
214
231
232
234
241
242
243
312
313
314
321
323
324
341
342
343
412
413
414
421
423
424
431
432
434

从代码优化的角度来讲,上面这段代码并不是很好,其中有些判断完全可以在外层循环来做,从而提高运行效率

digits=(1,2,3,4)
for i in digits:
    for j in digits:
        if j==i:
            continue
        for k in digits:
            if k==i or k==j:
                continue
            print(i*100+j*10+k)

进一步优化

def demo1(data,k=3):
    assert k==3,'k must be 3'
    for i in data:
        if i==0:continue
        ii=i*100
        for j in data:
            if j==i:
                continue
            jj=j*10
            for k in data:
                if k!=i and k!=j:
                    print(ii+jj+k)
#使用集合实现同样功能

def demo2(data,k=3):
    data=set(data)
    for i in data:
        if i==0:continue
        ii=i*100
        for j in data-{i}:
            jj=j*10
            for k in data-{i,j}:
                print(ii+jj+k)

例3-14:编写程序,生成一个含有20个随机数的列表,要求所有元素不相同,并且每个元素的值介于1到100之间

import random
x=[]
while True:
    if len(x)==20:
        break
    n=random.randint(1,100)
    if n not in x:
        x.append(n)
print(x)
print(len(x))
print(sorted(x))

#用集合来做更简单
from random import randint
x=set()
while len(x)<20:
    x.add(randint(1,100))
print(x)
print(sorted(x))

例3-15  编写程序,计算组合数C(n,i),即从n个元素中任选i个,有多少种选法。

     根据组合数定义,需要计算3个数的阶乘,在很多编程语言中都很难直接使用整型变量表示大数的阶乘结果,虽然Python并不存在这个问题,但是计算大数的阶乘仍需要相当多的时间。本例提供另一种计算方法:以Cni(8,3)为例,按定义式展开为Cni(8,3)=8!/3!/(8-3)!=(8*7*6*5*4*3*2*1) /(3*2*1)/ (5*4*3*2*1),对于(5,8]区间的数,分子上出现一次而分母上没出现;(3,5]区间的数在分子、分母上各出现一次;[1,3]区间的数分子上出现一次而分母上出现两次。

def Cnil(n,i):
    if not (isinstance(n,int)and isinstance(i,int) and n>=i):
        print('n and i must be integers and n must be larger than or equal to i.')
        return
    result=1
    Min,Max=sorted(i,n-i)
    for i in range(n,0,-1):
        if i>Max:
            result *=i
        elif i<=Min:
            result /=i
    return result

也可以使用math库中的阶乘函数直接按组合数定义实现。

>>> def Cni2(n, i):  

        import math   

       return int(math.factorial(n)/math.factorial(i)/math.factorial(n-i))

>>> Cni2(6,2)

15

还可以直接使用Python标准库itertools提供的函数。

itertools还提供了排列函数permutations()

itertools还提供了用于循环遍历可迭代对象元素的函数cycle()

itertools还提供了根据一个序列的值对另一个序列进行过滤的函数compress()

itertools还提供了根据函数返回值对序列进行分组的函数groupby()

例3-16   编写程序,计算理财产品收益,假设收益和本金一起滚动。

def licai(base,rate,days):
    #初始投资金额
    result=base
    #整除,用来计算一年可以滚动多少期
    times=365//days
    for i in range(times):
        result=result+result*rate/365*days
    return result
#14天理财,利率0,0385,投资十万
print(licai(1000000,0.0385,14))

例3-17  编写代码实现冒泡法排序。

from random import randint
def bubbleSort(lst):
    length=len(lst)
    for i in range(0,length):
        #比较相邻两个元素大小,并根据需要进行交换
        for j in range(0,length-i-1):
            if lst[j]>lst[j+1]:
                lst[j],lst[j+1]=lst[j+1],lst[j]
lst=[randint(1,100) for i in range(20)]
print('Before sort:\n',lst)
bubbleSort(lst)
print('After sort:\n',lst)

例3-18  编写代码实现选择法排序。

def selectSort(lst,reverse=False):
    length=len(lst)
    for i in range(0,length):
        m=i #假设剩余元素中第一个最小或者最大
        for j in range(i+1,length): #扫描剩余元素
            exp='lst[j]<lst[m]'
            if reverse:
                exp='lst[j]>lst[m]'
                #内置函数eval()用来对字符串进行求值
            if eval(exp):
                m=j
        if m!=i: #如果发现更小的或更大的,就交换值
            lst[i],lst[m]=lst[m],lst[i]

例3-19  二分法查找。

    二分法查找算法非常适合在大量元素中查找指定的元素,要求序列已经排好序(这里假设按从小到大排序),首先测试中间位置上的元素是否为想查找的元素,如果是则结束算法;如果序列中间位置上的元素比要查找的元素小,则在序列的后面一半元素中继续查找;如果中间位置上的元素比要查找的元素大,则在序列的前面一半元素中继续查找。重复上面的过程,不断地缩小搜索范围,直到查找成功或者失败(要查找的元素不在序列中)。

def binarySearch(lst, value):
    start = 0
    end = len(lst)
    while start < end:         
        middle = (start + end) // 2    #计算中间位置        
        if value == lst[middle]:         #查找成功,返回元素对应的位置
            return middle        
        elif value > lst[middle]:        #在后面一半元素中继续查找
            start = middle + 1        
        elif value < lst[middle]:        #在前面一半元素中继续查找
            end = middle - 1    
    return False                            #查找不成功,返回False



from random import randint

lst = [randint(1,50) for i in range(20)]
lst.sort()
print(lst)
result = binarySearch(lst, 30)
if result!=False:
    print('Success, its position is:',result)
else:
    print('Fail. Not exist.')

例3-20  编写程序,计算百钱买百鸡问题。假设公鸡5元一只,母鸡3元一只,小鸡1元三只,现在有100块钱,想买100只鸡,问有多少种买法?

#假设能买x只公鸡,x最大为20
for x in range(21):
    #假设能买y只母鸡,y最大为33
    for y in range(34):
        #假设能买z只小鸡
        z = 100-x-y
        if (z%3==0 and 5*x + 3*y + z//3 == 100):
              print(x,y,z)

例3-21  编写代码,模拟决赛现场最终成绩的计算过程。

#这个循环用来保证必须输入大于2的整数作为评委人数
while True:
    try:
        n = int(input('请输入评委人数:'))
        if n <= 2:
            print('评委人数太少,必须多于2个人。')
        else:
            #如果输入大于2的整数,就结束循环
            break
    except:
        pass
#用来保存所有评委的打分
scores = []
for i in range(n):
    #这个while循环用来保证用户必须输入0到100之间的数字
    while True:
        try:
            score = input('请输入第{0}个评委的分数:'.format(i+1))
            #把字符串转换为实数
            score = float(score)
            #用来保证输入的数字在0到100之间
            assert 0<=score<=100
            scores.append(score)
            #如果数据合法,跳出while循环,继续输入下一个评委的得分
#计算并删除最高分与最低分
highest = max(scores)
lowest = min(scores)
scores.remove(highest)
scores.remove(lowest)
#计算平均分,保留2位小数
finalScore = round(sum(scores)/len(scores), 2)

formatter = '去掉一个最高分{0}\n去掉一个最低分{1}\n最后得分{2}'
print(formatter.format(highest, lowest, finalScore))

            break
        except:
            print('分数错误')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值