Python期末考試總復(fù)習(xí)資料



前言

先來(lái)聽(tīng)一個(gè)恐怖故事??

在一個(gè)月黑風(fēng)高的夜晚??,林大夕可同學(xué)埋頭于昏黃的臺(tái)燈下,為不久之后的Python期末考試做著復(fù)習(xí)。時(shí)間不多了,他把重點(diǎn)放在輸入輸出,字符串、列表、字典的操作上,至于函數(shù)與類(lèi),只是匆匆掃了一眼,他認(rèn)為憑借著在字符串、列表、字典上較為熟練的操作,應(yīng)該就勉強(qiáng)能及格了。
可萬(wàn)萬(wàn)沒(méi)想到的是,不久之后的考場(chǎng)上,在瀏覽考題的那半分鐘里,仿佛是有數(shù)道驚雷在耳邊炸響——他復(fù)習(xí)的內(nèi)容全都沒(méi)考... 題目?jī)羰切┲T如帶有可變參數(shù)的函數(shù)、用類(lèi)實(shí)現(xiàn)發(fā)牌等等。
這樣一來(lái),林大夕可同學(xué)的補(bǔ)考也就隨之提上了日程。

這兩個(gè)月以來(lái),我斷斷續(xù)續(xù)地為Python補(bǔ)考做了很多準(zhǔn)備????♂?,包括

  1. 閱讀Python Cookbook約1/3的內(nèi)容
  2. 閱讀Python官方文檔中的入門(mén)教程與部分標(biāo)準(zhǔn)庫(kù)參考
  3. 完成PTA上的浙大版《Python 程序設(shè)計(jì)》題目集與學(xué)校老師出的5套題目集

在經(jīng)歷了這個(gè)過(guò)程后,很多Python相關(guān)的知識(shí)都能夠靈活運(yùn)用了~ ??

然而到目前為止,學(xué)校還沒(méi)通知補(bǔ)考時(shí)間和補(bǔ)考地點(diǎn)。再加上對(duì)翻書(shū)馬冬梅,考試孫紅雷的墻裂擔(dān)憂(yōu),我便把各種知識(shí)點(diǎn)與題型進(jìn)行了系統(tǒng)性的總結(jié),等到補(bǔ)考(很可能安排在下學(xué)期)前也不用到時(shí)候再四處找零散的復(fù)習(xí)資料了,將這份總結(jié)看上一看、練上一練,應(yīng)該會(huì)有事半功倍的效果。

同時(shí),希望這份Python總結(jié)也能夠幫助到很多正在為學(xué)校里的Python考試(尤其是試題以編程題居多的考試)而做著準(zhǔn)備??????的小可愛(ài)們~



一、知識(shí)儲(chǔ)備

1. 輸入輸出

1.1 輸入

1.1.1 拆分輸入數(shù)據(jù)

使用map()split()將輸入數(shù)據(jù)進(jìn)行拆分

注:map()split()的組合會(huì)自動(dòng)忽略空格

a, b, c = map(int, input().split())         # split()中為將元素拆分的標(biāo)志,默認(rèn)為空格

value = b*b - 4*a*c

print(value)

1.1.2 設(shè)定截止位

只要#之前的輸入內(nèi)容

a = input()
s = ''
for i in a:
  if i == '#':
    break
  s = s + i         # 將'#'前的輸入數(shù)據(jù)儲(chǔ)存到s中

1.1.3 去調(diào)輸入前后的空格

strip():去掉元素前后方的空格,但中間的空格不去掉

s1 = input().strip()
s2 = input().strip()

print(s1)
print(s2)

1.1.4 所輸即所得

eval():直接將字符串當(dāng)作有效的表達(dá)式(可以暫且理解為直接去掉字符串的雙引號(hào))

test = eval(input())        
# 嘗試輸入內(nèi)容1:[1, 2, 3, 4, 5]
# 嘗試輸入內(nèi)容2:{'John': 89, 'Dutton': 95}

print(test)
print(type(test))           # 查看經(jīng)過(guò)eval轉(zhuǎn)化后的類(lèi)型
result_dict = {"+": "x+y", "-": "x-y", "*": "x*y", "/": "x/y if y!=0  else 'divided by zero'"}

x = int(input())
op = input()
y = int(input())

result = eval(result_dict[op])
print(result)

1.2 輸出

1.2.1 格式化輸出format

: <填充> <對(duì)齊> <寬度> , <.精度> <類(lèi)型>
引導(dǎo)符號(hào) 用于填充的單個(gè)字符 < 左對(duì)齊 > 右對(duì)齊 ^居中對(duì)齊 輸出寬度 千位分隔符 小數(shù)部分的精度 整數(shù)類(lèi)型或浮點(diǎn)數(shù)類(lèi)型

{index : space . decimal_precision conversion_type}

a, b = map(int, input().split(","))

for i in range(a, b):
    print("{:^6d} | {:^6d} | {:^6d} | {:^6d}".format(i, i**2, i**3, i**4))

1.2.2 end

# python默認(rèn)輸出會(huì)換行
# 使用end=''可以將前后輸出內(nèi)容連接在一行
print("Linda", end='_') 
print("Silk")

2. 列表、元組、集合、字典

四者區(qū)別
# 創(chuàng)建空列表
empty_list = []
empty_list = list()

# 創(chuàng)建空元組
empty_tuple = ()
empty_tuple = tuple()

# 創(chuàng)建空集合
empty_set = {}      # ?錯(cuò)誤?。?!此方法用于創(chuàng)建字典
empty_set = set()

# 創(chuàng)建空字典
empty_dict = {}
empty_dict = dict()

2.1 列表

??注意:像 insert ,remove 或者 sort 能夠修改列表中元素的方法,沒(méi)有打印出返回值(它們返回默認(rèn)值 None ,這是Python中所有可變數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)原則)。

舉個(gè)栗子??

hosts = ['Dolores', 'Angela', 'Charlotte']

# 1. insert修改了原來(lái)的列表
hosts.insert(1, 'William')                          
print(hosts)                                # 直接調(diào)用原列表名,會(huì)得到修改后的列表

new_hosts = hosts.insert(2, 'Teddy')        # 若創(chuàng)建一個(gè)變量存放返回結(jié)果,變量的值會(huì)變?yōu)镹one
print(new_hosts)


# 2. index并未修改原來(lái)的列表
position = hosts.index('Dolores')           # 可創(chuàng)建一個(gè)變量存放返回結(jié)果
print(position)

2.1.1 增、刪、改、查

①. 增加/插入

  1. append():在list的最后加入一個(gè)元素

    courses = ['History', 'Math', 'Physics']
    
    courses.append('Art')
    
  1. extend():在list的最后加入一個(gè)列表

    courses = ['History', 'Math', 'Physics']
    courses_2 = ['Art', 'Education']
    
    courses.extend(courses2)
    
  1. insert():在list的某個(gè)位置加入一個(gè)元素

    courses = ['History', 'Math', 'Physics']
    
    courses.insert(0, 'Art')
    

②. 刪除

  1. remove():刪除list中的特定元素

    courses = ['History', 'Math', 'Physics']
    
    courses.remove('Math')
    
  1. pop():移除list最后一個(gè)元素

    courses = ['History', 'Math', 'Physics']
    
    courses.pop()
    

③. 修改

courses = ['History', 'Math', 'Physics']

courses[0] = 'Art'

④. 查詢(xún)

  1. index():查詢(xún)某元素的在列表中的位置(索引)

    courses = ['History', 'Math', 'Physics', 'CompSci']
    
    print(courses.index('CompSci'))
    
  1. in:查詢(xún)某元素是否在列表中

    courses = ['History', 'Math', 'Physics', 'CompSci']
    
    print('Art' in courses)
    

列表中用到:index(), in

字符串中用到:find(), count(), in

  • 使用find()時(shí),若查詢(xún)的元素存在,返回首次出現(xiàn)的位置索引;若不存在,返回 -1
  • 使用count()時(shí), 若查詢(xún)?cè)爻霈F(xiàn),返回出現(xiàn)次數(shù);若未出現(xiàn),返回 0
  • 使用in時(shí),返回值為TrueFalse

2.1.2 切片

語(yǔ)法:list_name [start_index : stop_index : step]

courses = ['History', 'Math', 'Physics', 'CompSci']

print(courses[0:2])

# step
print(courses[0:3:2])

# 若step為負(fù),則代表反向
print(courses[-1:0:-1])


# 理解切片
# 將索引視作指向字符之間 ,第一個(gè)字符的左側(cè)標(biāo)為0,最后一個(gè)字符的右側(cè)標(biāo)為n,其中n是字符串長(zhǎng)度。
# +---+---+---+---+---+---+
# | P | y | t | h | o | n |
# +---+---+---+---+---+---+
# 0   1   2   3   4   5   6

# 注意:切片的開(kāi)始總是被包括在結(jié)果中,而結(jié)束不被包括 <range()與之相同>。這使得s[:i] + s[i:]總是等于s
# word = 'Python'
# print(word[:2] + word[2:])

2.1.3 排序

  1. sort() / sorted() 順序

    courses = ['Math', 'History', 'Physics', 'CompSci']
    
    
    # 1. sort()
    # sort()會(huì)改變?cè)斜眄樞?courses.sort()
    print(courses)
    
    
    # 2. sorted()
    # sorted()不會(huì)改變?cè)斜眄樞?,它?huì)返回一個(gè)排序后的版本
    # 需創(chuàng)建一個(gè)變量來(lái)接收返回值
    sorted_courses = sorted(courses)
    print(sorted_courses)
    
  1. reverse() / reversed() / sort() / [::-1] 反轉(zhuǎn) / 倒序

    courses = ['Math', 'History', 'Physics', 'CompSci']
    
    
    # 1. reverse()
    # reverse()會(huì)改變?cè)斜眄樞?courses.reverse()
    print(courses)
    
    
    # 2. reversed()
    # sorted()不會(huì)改變?cè)斜眄樞?,它?huì)返回一個(gè)排序后的版本
    # 需創(chuàng)建一個(gè)變量來(lái)接收返回值
    reversed_courses = reversed(courses)
    print(reversed_courses)
    
    
    # 3. sort()
    # 用包含申明的sort方法
    courses.sort(reverse = True)
    print(courses)
    
    
    # 4. [::-1]
    print(courses[::-1])
    

2.1.4 去重

使用set(),因集合中沒(méi)有重復(fù)的元素

num_list = [1, 2, 3, 1, 2, 4, 2, 5, 3, 2, 6, 7]

print(set(num_list))

# 若要將去重的結(jié)果以列表表示
print(list(set(num_list)))

2.1.5 列表與字符串間的轉(zhuǎn)化

列表 --> 字符串:join()

字符串 --> 列表:split()

courses = ['History', 'Math', 'Physics', 'CompSci']

# 以逗號(hào)和空格結(jié)合列表中的元素,將其變?yōu)橐婚L(zhǎng)串字符串
course_str = ', '.join(courses)

# 使用split()將字符串重新變換為列表
new_list = course_str.split(', ')

2.1.6 列表推導(dǎo)式

列表推導(dǎo)式的結(jié)構(gòu)是由一對(duì)方括號(hào)所包含的以下內(nèi)容:一個(gè)表達(dá)式,后面跟一個(gè) for 子句,然后是零個(gè)或多個(gè) forif 子句。

其結(jié)果將是一個(gè)新列表,由對(duì)表達(dá)式依據(jù)后面的 forif 子句的內(nèi)容進(jìn)行求值計(jì)算而得出。

舉個(gè)栗子??

# 為了創(chuàng)建一個(gè)求平方的列表
# 1. 普通方法
squares = []

for x in range(10):
    squares.append(x**2)
    
print(squares)


# 2. 列表推導(dǎo)式
squares = [x**2 for x in range(10)]         # for前方的內(nèi)容為返回值

print(squares)
# 用列表推導(dǎo)式來(lái)將輸入值處理為矩陣
m, n = map(int, input().split())        # m為行,n為列,其間用空格隔開(kāi)
matrix = []

for i in range(m):                                  # 重復(fù)m次(m行)
    s = input()                                     # 輸入n個(gè)數(shù),每個(gè)數(shù)之間用空格隔開(kāi)
    matrix.append([int(n) for n in s.split()])      # ??注意:將每個(gè)元素轉(zhuǎn)化為整型

print(matrix)

2.1.7 最值 / 求和

對(duì)于可迭代對(duì)象,可以直接用sum(), max(), min()方法來(lái)進(jìn)行快速計(jì)算

nums = [1, 5, 2, 6, 3, 4]

print(min(nums))
print(max(nums))
print(sum(nums))

2.2 元組

courses = ('History', 'Math', 'Physics')

print(courses)

courses[0] = 'Art'          # ?錯(cuò)誤: 元組內(nèi)元素為只讀,不可更改

print(courses)

2.3 集合

courses = {'History', 'Math', 'Physics', 'CompSci', 'Math'}

# 重復(fù)執(zhí)行多次,輸出結(jié)果不同
# 因set不注重內(nèi)部元素順序
# set會(huì)自動(dòng)消除元素重復(fù)部分
print(courses)

# 當(dāng)判斷某元素是否在一群元素中時(shí),set是首選項(xiàng)
print('Math' in courses)

集合間的運(yùn)算

cs_courses = {'History', 'Math', 'Physics', 'CompSci'}
art_courses = {'History', 'Math', 'Art', 'Design'}

# 交集(共有的元素)
print(cs_courses.intersection(art_courses))

# 不同(獨(dú)有的元素)
print(cs_courses.difference(art_courses))

# 并集(所有的元素)
print(cs_courses.union(art_courses))

2.4 字典

從某種程度上來(lái)說(shuō),可以將字典看做一個(gè)自定義索引(index)的列表

  • 列表中的某個(gè)元素可以表示為:list[index]

  • 字典中的某個(gè)值可以表示為:dict[key]

student = {'name': 'John', 'age': 25, 'courses': ['Math', 'CompSci']}

# get方法可以使得在字典中缺少要查詢(xún)的值時(shí)顯示出默認(rèn)或自定義的結(jié)果,而不是拋出異常
# 括號(hào)內(nèi)第二個(gè)參數(shù)為自定義默認(rèn)輸出內(nèi)容
print(student.get('name'))
print(student.get('phone', 'Sorry. Not Found~'))


# ------------------------
# 添加
student['phone'] = '199-8011-8011'
# 更新
student['name'] = 'Jane'

print(student)


# ------------------------
# 使用update可以一次更新多個(gè)值?。?!
student.update({'name': 'Silk', 'age': 100, 'phone': '188-0525-7633'})

print(student)


# ------------------------
# 刪除 方法一:使用del
del student['age']
# 刪除 方法二:使用pop
# pop會(huì)刪除該值,但也會(huì)同時(shí)返回刪除的值,需用變量來(lái)接收
age = student.pop('age')

print(student)
print(age)


# ------------------------
# 查看長(zhǎng)度
print(len(student))
# 查看鍵
print(student.keys())
# 查看值
print(student.values())
# 成對(duì)展現(xiàn)鍵與值
print(student.items())

重點(diǎn)

# 以鍵循環(huán)
for key in student:
    print(key)
    
# 鍵、值循環(huán)
for key, value in student.items():
    print(key, value)

3. 函數(shù)、類(lèi)、異常

3.1 函數(shù)

函數(shù)參數(shù)中arg表示:傳入的一個(gè)參數(shù)

函數(shù)參數(shù)中有單星號(hào)的*args 表示:將參數(shù)以元組的形式導(dǎo)入(不限個(gè)數(shù))

函數(shù)參數(shù)中有雙星號(hào)的**kwargs 表示:將參數(shù)以字典的形式導(dǎo)入(不限個(gè)數(shù))

from datetime import date


def mission(arg, *args, **kwargs):
    information = []
    for i in args:
        information.append(i)

    print('New Mission')
    print('------------------------------')
    print('System date: {}'.format(arg))
    print('Location: {}, {}'.format(information[0], information[1]))
    print('Mission ID: {}'.format(information[2]))
    print('------------------------------')

    for k, v in kwargs.items():
        print('{:8}········ {}'.format(k, v))


mission(date.today(), 'Berlin', 'German', 293821, AGENT='Jason Bourne', GENDER='Male', PROJECT='Treadstone')

3.2 類(lèi)

舉個(gè)栗子??

class MyDog:
    kind = 'Labrador'

    def __init__(self, name):
        self.name = name
        self.tricks = []            # 實(shí)例變量(每個(gè)實(shí)例的變量都不盡相同)

    def add_tricks(self, *trick):
        for i in trick:
            self.tricks.append(i)


dog1 = MyDog('Tommy')
dog2 = MyDog('Tom Me')
dog1.add_tricks('Bark', 'Slaughter')
dog2.add_tricks('Embark', 'Laughter')

print('My Dogs Info:')
print('-------------')
print('Dog1: {}--{}--{}'.format(dog1.kind, dog1.name, dog1.tricks))
print('Dog2: {}--{}--{}'.format(dog2.kind, dog2.name, dog2.tricks))

3.3 異常

a = input('Enter a number: ')

try:
    b = 5/int(a)
    print(b)
except ZeroDivisionError as err:                # 輸入為0時(shí)執(zhí)行
    print("There's a problem:", err)
except ValueError:                              # 輸入不為數(shù)字時(shí)執(zhí)行
    print('You entered a wrong value!')
else:                                           # 輸入為非零數(shù)字時(shí)執(zhí)行
    print('try語(yǔ)句能順利執(zhí)行時(shí),打印此句~')

4. 一些常用的方法

4.1 判斷數(shù)字、字母、大小寫(xiě)、空格

判斷是否為數(shù)字:isdigit();判斷是否為字母:isalpha()

是否為大寫(xiě)字母:isupper();是否為小寫(xiě)字母:islower()

判斷是否為空格:isspace()

# ~ 原方法 ~
# 使用列表儲(chǔ)存數(shù)字,隨后再轉(zhuǎn)化為字符串,最后轉(zhuǎn)化為整形
a = input()
b = []                      # 列表存放數(shù)據(jù)
for i in a :
   if i.isdigit() :
      b.append(n)
print(int("".join(b)))


# ~ 改進(jìn)版方法 ~
# 字符串可以通過(guò)+來(lái)連接。因此,可以用字符串來(lái)存儲(chǔ)數(shù)字。之后就不用再進(jìn)行轉(zhuǎn)化了
a = input()
b = ''                      # 字符串存放數(shù)據(jù)
for i in a:
  if i.isdigit():
    b += i                  # 直接通過(guò)'+'將字符連接
print(b)

4.2 編碼與轉(zhuǎn)化

4.2.1 UTF-8編碼

使用encode()方法

注意:編碼格式需要被引號(hào)包含

s = '人生苦短,我用Python'

print(s.encode('UTF-8'))

4.2.2 ASCII碼與字符的互換

使用ord()chr()

# 字符 --> ASCII
character = 'z'
print(ord(character))

# ASCII --> 字符
ascii = 126
print(chr(ascii))

有時(shí)還需根據(jù)ASCII碼的相加關(guān)系來(lái)做出一些限定,如'A' + 'Z' = 155

4.2.3 進(jìn)制轉(zhuǎn)化

①. 其它進(jìn)制轉(zhuǎn)化為十進(jìn)制

?使用int(x, y)將其他進(jìn)制轉(zhuǎn)化為十進(jìn)制。其中x為原值,y為原進(jìn)制

# 將8進(jìn)制的56轉(zhuǎn)化為十進(jìn)制
print(int(56, 8))       # 56需要加上'',即轉(zhuǎn)化為字符串形式

②. 十進(jìn)制轉(zhuǎn)化為其它進(jìn)制

# 轉(zhuǎn)化為二進(jìn)制:bin
print(bin(1024))

# 轉(zhuǎn)化為八進(jìn)制:oct
print(oct(8732))

# 轉(zhuǎn)化為十六進(jìn)制:hex
print(hex(2918))

4.3 判斷某個(gè)字符(串)是否屬于另一個(gè)字符串

string_1 = input('1st string: ')
string_2 = input('2nd string: ')

# 方法一:使用find()
# 如果字符串1包含字符串2,返回字符串2在1中的起始索引
# 如果不包含,則返回?'-1'?
print(string_1.find(string_2))


# 方法二:使用count()
# 若出現(xiàn),返回出現(xiàn)次數(shù);若未出現(xiàn),返回0
print(string_1.count(string_2))


# 方法三:使用in
# 返回值為'True'或'False'
print(string_2 in string_1)

4.4 替換

message = "I like you!"

trim = message.replace("l", "n")

print('Then:', message)         # 由此可知,replace并不改變?cè)址?。故需要?jiǎng)?chuàng)建新變量來(lái)接收
print('Now:', trim)

4.5 獲取幫助

使用dir()help()來(lái)查詢(xún)方法該如何使用

greeting = 'Hello'
name  = 'Silk'

# dir()能顯示括號(hào)內(nèi)變量所有操作的函數(shù)、方法
print(dir(name))


# help()能顯示某函數(shù)/方法的具體用法
# 括號(hào)內(nèi)不能是變量名
print(help(str))

# 查詢(xún)具體的某函數(shù)/方法
print(help(str.lower))

5. 一些常用的庫(kù)

5.1 math

①. 平方根:sqrt()

# 先導(dǎo)入math
import math

a, b, c = map(int, input().split())

s = (a + b + c)/2
# 使用sqrt()求平方根
area = math.sqrt(s*(s - a)*(s - b)*(s - c))     

②. 冪:pow(x, y)

import math

# 使用pow()計(jì)算3**4
d = math.pow(3, 4)

③. π:pi

# 使用pi獲取π值
num = math.pi

5.2 random

①. random():返回一個(gè)在區(qū)間[0.0, 1.0)的隨機(jī)浮點(diǎn)數(shù)

import random

for i in range(10):
    print(random.random())

②. randint(a, b):返回一個(gè)在區(qū)間[a, b]的隨機(jī)整數(shù),相當(dāng)于randrange(a, b+1)

import random

for i in range(10):
    print(random.randint(1, 15))

③. randrange(start, stop[, step]):從 range(start, stop, step) 返回一個(gè)隨機(jī)選擇的元素

import random

for i in range(10):
    print(random.randrange(5, 120, 10))

④. seed():獲取某種特定生成的隨機(jī)數(shù)
當(dāng)seed()無(wú)參數(shù)時(shí),每次生成的隨機(jī)數(shù)不同,
當(dāng)seed()有參數(shù)時(shí),若參數(shù)相同,則每次生成的隨機(jī)數(shù)相同;若參數(shù)不同,則生成的隨機(jī)數(shù)也不同

import random

ls = [1, 2, 3, 4, 5, 6, 7, 8]

for i in range(8):
    random.seed(4)                  # 試著改變seed()中的數(shù)或者注釋掉這一行,看看輸出的變化
    print(random.randint(1, 10))    # randint(a, b)隨機(jī)生成[a, b]間的整數(shù)

# 注意??:randint與range取值范圍的區(qū)別。前者能取右側(cè)的值,后者不能

⑤. shuffle():將一個(gè)序列(列表、字符串或元組)的順序打亂

import random

mylist = ["apple", "banana", "cherry"]
random.shuffle(mylist)

print(mylist)

5.3 datetime

獲取今天的日期

from datetime import date

day = date.today()
print(day)


二、題目練習(xí)

1. 語(yǔ)言相關(guān)

1.1 打印一些形狀

1.1.1 四種直角三角型

①. 直角在左上方

# 打印形狀 #
*****
****
***
**
*

# 實(shí)現(xiàn)代碼 #
# 輸入層數(shù)
a = int(input('請(qǐng)輸入層數(shù):'))

for i in range(a):
    print('*'*(a - i))          # 若要使打印出的星號(hào)??之間有空格,將'*'改為'* '即可

②. 直角在左下方

# 打印形狀 #
*
**
***
****
*****

# 實(shí)現(xiàn)代碼 #
# 輸入層數(shù)
a = int(input('請(qǐng)輸入層數(shù):'))

for i in range(a):
    print('*'*(i + 1))

③. 直角在右上方

# 打印形狀 #
*****
 ****
  ***
   **
    *

# 實(shí)現(xiàn)代碼 #
# 輸入層數(shù)
a = int(input('請(qǐng)輸入層數(shù):'))

# 可以將第三第四種三角形看作一個(gè)由' '和'*'組成的矩形,
# >>> 因此,每行的' '和'*'數(shù)量相加必等于a <<<
for i in range(a):
    print(' '*i + '*'*(a - i))

④. 直角在右下方

# 打印形狀 #
    *
   **
  ***
 ****
*****

# 實(shí)現(xiàn)代碼 #
# 輸入層數(shù)
a = int(input('請(qǐng)輸入層數(shù):'))

# 可以將第三第四種三角形看作一個(gè)由' '和'*'組成的矩形,
# >>> 因此,每行的' '和'*'數(shù)量相加必等于a <<<
for i in range(a):
    print(' '*(a - 1 - i) + '*'*(i + 1))

1.1.2 兩種九九乘法表

①. 常規(guī)

九九乘法表重點(diǎn)在于由兩個(gè)for循環(huán)控制輸出
核心是第二個(gè)循環(huán)的范圍由第一個(gè)循環(huán)的參數(shù)決定

常規(guī)九九乘法表
# 輸入層數(shù)
a = int(input('請(qǐng)輸入層數(shù):'))

for i in range(1, 10):
    for j in range(1, i+1):
        print('{}*{}={:<5d}'.format(j, i, i*j), end='')     # 使用format格式化輸出
    print()

②. 非常規(guī)

非常規(guī)九九乘法表
# 輸入層數(shù)
a = int(input('請(qǐng)輸入層數(shù):'))

for i in range(1, 10):
    for j in range(i, 10):
        print('{}*{}={:<5d}'.format(i, j, i*j), end='')     # 使用format格式化輸出
    print()

1.1.3 三種金字塔

①. 正金字塔

# 打印形狀 #
    *
   ***
  *****
 *******
*********
    
# 實(shí)現(xiàn)代碼 #
# 將金字塔看作一個(gè)由左邊矩形、右邊三角形組成的圖形(拆分如下)
# for i in range(a):
#     print('~'*(a - 1 - i) + '*'*(i + 1) + '  ' + '*'*i)

# 輸入層數(shù)
a = int(input('請(qǐng)輸入層數(shù):'))

for i in range(a):
    print(' '*(a - 1 - i) + '*'*(i + 1) + '*'*i)

②. 倒金字塔

# 打印形狀 #
*********
 *******
  *****
   ***
    *
    
# 實(shí)現(xiàn)代碼 #
# 輸入層數(shù)
a = int(input('請(qǐng)輸入層數(shù):'))

for i in range(a):
    print(' '*i + '*'*(a - i) + '*'*(a - 1 - i))

③. 數(shù)字金字塔

# 打印形狀 #
          0
        1 0 1
      2 1 0 1 2
    3 2 1 0 1 2 3 
  4 3 2 1 0 1 2 3 4
5 4 3 2 1 0 1 2 3 4 5
    
# 實(shí)現(xiàn)代碼 #
# 輸入層數(shù)
a = int(input('請(qǐng)輸入層數(shù):'))

for i in range(a+1):
    # 調(diào)節(jié)數(shù)字前方空格數(shù)量
    # 可針對(duì)層數(shù)為一位數(shù)、兩位數(shù)的金字塔打印
    if i < 10:                                              
        print(' '*(a - 8) + '  '*(a + 1 - i), end='')
    else:
        print('   ' * (a + 1 - i), end='')

    # 輸出金字塔左半部分(包括0)
    j = i
    while j != -1:
        print(j, end=' ')
        j = j - 1

    # 輸出金字塔右半部分(不包括0)
    j = 1
    while j != i + 1:
        print(j, end=' ')
        j = j + 1

    print()

1.2 猜詞

①. 題目??

隨機(jī)給出一個(gè)1~100之間的數(shù)字,然后讓玩家猜這個(gè)數(shù)字。如果沒(méi)有猜出正確答案,給出“大了”還是“小了”的提示;如果猜出正確答案,打印出“恭喜,你猜了X次猜對(duì)了答案!”。
每個(gè)玩家有5次猜數(shù)字的機(jī)會(huì),如果5次都沒(méi)有猜對(duì),給出“是否繼續(xù)游戲”的提示。

輸出樣例

猜數(shù)字游戲?。ㄕ?qǐng)給出1-100之間的數(shù)字)
請(qǐng)輸入你猜的數(shù)字:69
猜的數(shù)字大了...
請(qǐng)輸入你猜的數(shù)字:28
猜的數(shù)字小了...
請(qǐng)輸入你猜的數(shù)字:60
猜的數(shù)字小了...
請(qǐng)輸入你猜的數(shù)字:65
猜的數(shù)字小了...
請(qǐng)輸入你猜的數(shù)字:68
猜的數(shù)字大了...
次數(shù)用完啦!是否重新開(kāi)始?(y/n):y
猜數(shù)字游戲!(請(qǐng)給出1-100之間的數(shù)字)
請(qǐng)輸入你猜的數(shù)字:60
猜的數(shù)字大了...
請(qǐng)輸入你猜的數(shù)字:50
猜的數(shù)字小了...
請(qǐng)輸入你猜的數(shù)字:55
恭喜,你猜了3次猜對(duì)了答案
是否重新開(kāi)始猜數(shù)字游戲?(y/n):n

Process finished with exit code 0

②. 題解?

思路

把用于存放輸入是否繼續(xù)(y或者n)的變量設(shè)定為y,然后將其當(dāng)做是否進(jìn)行while循環(huán)的標(biāo)準(zhǔn)

代碼

import random

# 將輸入賦值為'y'
inp = 'y'

while inp == 'y':
    print('猜數(shù)字游戲?。ㄕ?qǐng)給出1-100之間的數(shù)字)')
    generate = random.randint(1, 100)
    # print(generate)                                           # 顯示生成數(shù),方便測(cè)試

    # 5次機(jī)會(huì)
    for flag in range(6):                                       # 范圍[0, 5]是為了將次數(shù)用完后的輸出部分放入循環(huán)來(lái)判斷
        if flag == 5:
            inp = input('次數(shù)用完啦!是否重新開(kāi)始?(y/n):')
            break
        else:
            num = int(input('請(qǐng)輸入你猜的數(shù)字:'))
            if num < generate:
                print('猜的數(shù)字小了...')
            elif num > generate:
                print('猜的數(shù)字大了...')
            else:
                print('恭喜,你猜了{(lán)}次猜對(duì)了答案'.format(flag + 1))
                inp = input('是否重新開(kāi)始猜數(shù)字游戲?(y/n):')
                break

1.3 字符串、列表操作

1.3.1 刪除重復(fù)字符串

①. 題目

本題目要求找出輸入字符串中重復(fù)的字符,并輸出去掉重復(fù)字符后的字符串以及重復(fù)的字符是哪些,重復(fù)了幾次。

1.1 輸入格式

輸入一個(gè)字符串。

1.2 輸出格式

輸出去掉重復(fù)字符的字符串,每個(gè)重復(fù)的字符重復(fù)了幾次。

1.3 輸入樣例

ajlrihvnvgugnmkh

1.4 輸出樣例

ajlrihvngumk
v 2
g 2
n 2
h 2

②. 題解?

2.1 思路

關(guān)鍵:創(chuàng)建兩個(gè)空字符串和一個(gè)空字典??

  • 字符串1用來(lái)存儲(chǔ)輸入字符串中沒(méi)有重復(fù)的字符
  • 字符串2用來(lái)存儲(chǔ)剩下的字符(重復(fù)的字符)
  • 字符串2的字符當(dāng)作key??、字符的重復(fù)次數(shù)當(dāng)作value依次存入字典

2.2 代碼

string = input()
result_str = ''
redundant_str = ''
dic = {}

for i in string:
    if i not in result_str:
        result_str += i         # 將非重復(fù)的字符依次存入result_str
    else:
        redundant_str += i      # 將重復(fù)的字符依次存入redundant_str

for i in redundant_str:         # 將redundant_str中的元素存入字典
    if i not in dic:
        dic[i] = 2              # 元素已經(jīng)在result_str中存在,故redundant_str中出現(xiàn)的應(yīng)該記為第二個(gè)
    else:
        dic[i] += 1             # 若元素已在dic中存在,鍵值 +1

print(result_str)

for k, v in dic.items():        # 遍歷字典,輸出鍵值對(duì)
    print('{} {}'.format(k, v))

1.3.2 求單詞長(zhǎng)度并排序

①. 題目??

輸入n個(gè)單詞,計(jì)算每個(gè)單詞長(zhǎng)度。對(duì)單詞長(zhǎng)度排序,分行輸出單詞長(zhǎng)度及其單詞。

1.1 輸入格式

行1:?jiǎn)卧~個(gè)數(shù)n
分行輸入n個(gè)單詞

1.2 輸出格式

分行輸出單詞長(zhǎng)度及其單詞。(單詞長(zhǎng)度,單詞)用元組表示

1.3 輸入樣例

5
python
list
set
996
tuple

1.4 輸出樣例

(3, '996')
(3, 'set')
(4, 'list')
(5, 'tuple')
(6, 'python')

②. 題解?

2.1 思路

關(guān)鍵:創(chuàng)建一個(gè)空字符串和一個(gè)空字典??

  • 字符串用來(lái)存儲(chǔ)依次輸入的字符串
  • 字符串排序后(將形如'996'的數(shù)字字符串排到字母字符串'set'前面)的元素當(dāng)作key??、元素(每個(gè)字符)的長(zhǎng)度當(dāng)作value依次存入字典
  • 字典以值的大小排序(參考:lambda表達(dá)式的用法

??注意:字典按值排序后返回值是元素為集合列表,每個(gè)集合即為原字典中的一個(gè)鍵值對(duì)。

2.2 代碼

a = int(input())
ls = []
dic = {}

for i in range(a):
    temp = input()
    ls.append(temp)     # 將輸入字符串依次存入ls

for i in sorted(ls):    # 對(duì)ls排序后進(jìn)行迭代
    dic[i] = len(i)     # 將ls中的元素與對(duì)應(yīng)的長(zhǎng)度存入字典


new_dic = sorted(dic.items(), key=lambda item: item[1])     # 對(duì)字典按值排序

for i in new_dic:
    print("({}, '{}')".format(i[1], i[0]))

1.3.3 學(xué)生成績(jī)處理

①. 題目??

小明在幫助老師統(tǒng)計(jì)成績(jī),老師給他的是一組數(shù)據(jù)。數(shù)據(jù)的第1行代表學(xué)生數(shù)n,后面的n行代表每個(gè)學(xué)生的成績(jī)。成績(jī)是整數(shù)類(lèi)型。
小明編寫(xiě)了一個(gè)程序,該程序可以批量處理數(shù)據(jù),統(tǒng)計(jì)所有學(xué)生的平均分。當(dāng)數(shù)據(jù)沒(méi)有任何錯(cuò)誤時(shí),提示'All OK',當(dāng)數(shù)據(jù)有一些錯(cuò)誤(某行是浮點(diǎn)數(shù)、某行是非整數(shù)字符)時(shí),可以提示哪些數(shù)據(jù)出錯(cuò),并最后提示第幾行出錯(cuò),出錯(cuò)的原因,共出錯(cuò)多少行。對(duì)于另一些小錯(cuò)誤,如某行雖然是整數(shù),但是左右有多余的空格,可以將空格去除掉進(jìn)行正常統(tǒng)計(jì)。

在最后輸出:
共處理多少行數(shù)據(jù),幾行正確,幾行錯(cuò)誤,平均成績(jī)(保留兩位小數(shù))。

進(jìn)階要求:
有可能碰到要求輸入n行,后面的數(shù)據(jù)卻小于n行。要求處理這種情況。碰到這種情況。
輸出end of files,并統(tǒng)計(jì)現(xiàn)有行數(shù)。見(jiàn)樣例3

1.1 輸入樣例1

3
1
    2    
3

1.2 輸出樣例1

Total: 3
OK: 3
Error: 0
avg grade = 2.00

1.3 輸入樣例2

5
1
  2
   a  
  b  5
3

1.4 輸出樣例2

line 3 error for input "   a  "
line 4 error for input "  b  5"
Total: 5
OK: 3
Error: 2
avg grade = 2.00

1.5 輸入樣例3

5
 a
 2    
3

1.6 輸出樣例3

line 1 error for input " a"
end of files
Total: 3
OK: 2
Error: 1
avg grade = 2.50

提示:對(duì)于樣例3,如果是在IDLE中進(jìn)行測(cè)試,可在輸入最后一行并回車(chē)后,按Ctrl+D結(jié)束輸入。

②. 題解?

2.1 思路

  • 通過(guò)第一行的輸入數(shù)字來(lái)作為循環(huán),確定隨后輸入的行數(shù)
  • 通過(guò)strip()來(lái)去掉輸入部分多余的空格
  • 通過(guò)isdecimal()來(lái)判斷是否為整數(shù)
  • 字典將格式錯(cuò)誤的行數(shù)與對(duì)應(yīng)的內(nèi)容存入,之后再格式化輸出

注:暫未完成進(jìn)階要求中的內(nèi)容

2.2 代碼

total_num = int(input())
ok = 0
error = 0
total = 0
dic = {}

for i in range(total_num):
    temp = input()
    trim = temp.strip()
    if trim.isdecimal():
        ok += 1
        total += int(trim)
    else:
        dic[i + 1] = temp
        error += 1

for k, v in dic.items():
    print('line {} error for input "{}"'.format(k, v))
print('Total:', total_num)
print('OK:', ok)
print('Error:', error)
print('avg grade = {:.2f}'.format(total/ok))

1.4 可變參數(shù)傳遞

* 本題含有計(jì)算年齡的方法 *

①. 題目??

本題要求實(shí)現(xiàn)一個(gè)函數(shù),可輸出姓名、出生日期、性別、國(guó)籍和電話,并根據(jù)出生日期算出歲數(shù)(需要判斷是否足歲)。函數(shù)可以對(duì)輸入中的錯(cuò)誤信息進(jìn)行捕獲。

1.1 函數(shù)接口定義

def student(name,*birth,**information)

1.2 裁判測(cè)試程序樣例

name = input()
birth = input()
student(name,birth,sex='Female', nation='China', phone='123456789')

1.3 輸入樣例1

zhangsan
1999 2 3

1.4 輸出樣例1

name:zhangsan
birth:1999-2-3
age is 20
sex:Female
nation:China
phone:123456789

1.5 輸入樣例2

zhangsan
1999-2-3

1.6 輸出樣例2

name:zhangsan
The interval in the input 'birth' is a space

②. 題解?

2.1 知識(shí)儲(chǔ)備

函數(shù)參數(shù)前的單星號(hào)*args 表示:將參數(shù)以元組的形式導(dǎo)入
函數(shù)參數(shù)前的雙星號(hào)**kwargs 表示:將參數(shù)以字典的形式導(dǎo)入

2.2 代碼

from datetime import date


def student(name, *birth, **information):
    string = birth[0]               # 將出生日期轉(zhuǎn)化為字符串
    if ' ' not in string:           # 這里僅判斷出生日期不以空格為間隔的情況
        print('name:{}'.format(name))
        print("The interval in the input 'birth' is a space")
    else:
        ls = string.split()         # 將字符串轉(zhuǎn)化為列表
        year = ls[0]                # 切片儲(chǔ)存
        month = ls[1]
        day = ls[2]
        today = date.today()        # 獲取今天的日期
        age = today.year - int(year) - ((today.month, today.day) < (int(month), int(day)))      # ??重要?。?!計(jì)算年齡
        print('name:{}'.format(name))
        print('{}-{}-{}'.format(year, month, day))
        print('age is', age)
        for k, v in information.items():
            print('{}:{}'.format(k, v))


name = input()
birth = input()
student(name, birth, sex='Female', nation='China', phone='123456789')

1.5 圓球類(lèi)、學(xué)生類(lèi)

1.5.1 圓球類(lèi)計(jì)算圓周長(zhǎng)面積、球表面積體積

①. 題目??

編寫(xiě)程序,創(chuàng)建類(lèi)MyMath,計(jì)算圓的周長(zhǎng)、面積和球的表面積和體積,結(jié)果均保留兩位小數(shù)。
若輸入的是非數(shù)字,則輸出:請(qǐng)輸入數(shù)字!
提示:要引入math包

1.1 輸入樣例1

輸入半徑

5

1.2 輸出樣例1

圓的周長(zhǎng) = 31.42
圓的面積 = 78.54
球的表面積 = 314.16
球的體積 = 523.60

1.3 輸入樣例2

s

1.4 輸出樣例2

請(qǐng)輸入數(shù)字!

②. 題解?

2.1 知識(shí)儲(chǔ)備

球的體積:V = 4πR3/3
球的面積:S = 4πR^2
表面積:Surface Area / 體積:Volume / 周長(zhǎng):Perimeter / 面積:Area

2.2 代碼

import math


class MyMath:
    def __init__(self, r):
        self.r = r

    def perimeter(self):
        print('圓的周長(zhǎng) = {:.2f}'.format(2*math.pi*r))

    def area(self):
        print('圓的面積 = {:.2f}'.format(math.pi*math.pow(r, 2)))

    def surface(self):
        print('球的表面積 = {:.2f}'.format(4*math.pi*math.pow(r, 2)))

    def volume(self):
        print('球的體積 = {:.2f}'.format(4/3*math.pi*math.pow(r, 3)))


r = input()

if r.isdigit():
    r = int(r)
    p1 = MyMath(r)
    p1.perimeter()
    p1.area()
    p1.surface()
    p1.volume()
else:
    print('請(qǐng)輸入數(shù)字!')

1.5.2 學(xué)生類(lèi)計(jì)算年齡、成績(jī)等級(jí)

①. 題目??

編寫(xiě)個(gè)學(xué)生類(lèi)Student

  • 包含姓名、出生日期和成績(jī)屬性(數(shù)據(jù)成員);
  • 包含一個(gè)用于給定數(shù)據(jù)成員初始值的構(gòu)造函數(shù)
  • 包含一個(gè)可計(jì)算學(xué)生年齡的方法(學(xué)生年齡判斷根據(jù)日期是否超過(guò)生日的年、月、日);
  • 包含一個(gè)將成績(jī)對(duì)應(yīng)成等級(jí)的方法
  • 包含一個(gè)輸出“姓名+年齡+成績(jī)等級(jí)”的方法。

1.1 輸入樣例1

Name: LindaSilk
Birth: 2016-08-24
Grade(0~100): 99

1.2 輸出樣例1

姓名: LindaSilk  年齡: 3  成績(jī): 優(yōu)

1.3 輸入樣例2

Name: 林大夕可
Birth: 2000-02-29
Grade(0~100): 85

1.4 輸出樣例2

姓名: 林大夕可  年齡: 20  成績(jī): 良

②. 題解?

2.1 代碼

from datetime import date


class Student:
    def __init__(self, name, birth, grade):
        self.name = name
        self.birth = birth
        self.grade = grade

    def calculate_age(self):
        today = date.today()                                    # 獲取今天的日期
        year, month, day = map(int, self.birth.split('-'))      # 將birth以'-'拆分儲(chǔ)存為年、月、日
        age = (today.year - year - ((today.month, today.day) < (month, day)))
        return age

    def classify(self):
        dic = {
            '優(yōu)': [90, 100],
            '良': [80, 89],
            '中': [70, 79],
            '及格': [60, 69],
            '不及格': [0, 59]
        }                                                       # 用字典方法判斷等級(jí)
        for k, v in dic.items():
            if v[0] <= self.grade <= v[1]:
                return k

    def out(self):
        print('姓名: {}  年齡: {}  成績(jī): {}'.format(self.name, self.calculate_age(), self.classify()))


name = input('Name: ')
birth = input('Birth: ')
grade = input('Grade(0~100): ')

s1 = Student(name, birth, int(grade))
s1.out()                                                        # 調(diào)用Student類(lèi)中的out方法

2. 算法相關(guān)

2.1 素?cái)?shù)

1. 知識(shí)儲(chǔ)備

質(zhì)數(shù)(Prime Number),又稱(chēng)素?cái)?shù),是指大于1的自然數(shù)中,除了1和它本身,沒(méi)有其他因數(shù)的數(shù)

2. 代碼

number = int(input('請(qǐng)輸入一個(gè)數(shù):'))


def is_prime(num):
    if num > 1:
        for i in range(2, num):
            if num % i == 0:
                return False
        else:
            return True
    else:
        return False


if is_prime(number) is True:
    print('{}是素?cái)?shù)'.format(number))
else:
    print('{}不是素?cái)?shù)'.format(number))

2.2 斐波那契數(shù)

①. 知識(shí)儲(chǔ)備??

斐波那契數(shù)列(Fibonacci sequence),又稱(chēng)黃金分割數(shù)列。因意大利數(shù)學(xué)家Leonardo Fibonacci以兔子繁殖為例子而引入,故又稱(chēng)為“兔子數(shù)列”
指的是這樣一個(gè)數(shù)列:1、1、2、3、5、8、13、21、34、……

在數(shù)學(xué)上,斐波那契數(shù)列被以遞推的方法定義:
F(1) = 1,F(xiàn)(2) = 1, F(n) = F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*)

②. 幾種情形??

2.2.1 求第n個(gè)斐波那契數(shù)(核心)

運(yùn)行效果?

請(qǐng)輸入數(shù)字:10
第10個(gè)斐波那契數(shù):55

方法一:使用for循環(huán)

num = int(input('請(qǐng)輸入數(shù)字:'))


def fib1(n):
    a, b = 1, 1
    for j in range(n - 1):          # ??
        a, b = b, a + b
    return a


print('第{}個(gè)斐波那契數(shù):{}'.format(num, fib1(num)))        

方法二:使用遞歸

num = int(input('請(qǐng)輸入數(shù)字:'))


def fib2(n):
    if n == 1 or n == 2:
        return 1
    else:
        return fib2(n - 1) + fib2(n - 2)
  
        
print('第{}個(gè)斐波那契數(shù):{}'.format(num, fib2(num)))        

2.2.2 求前n個(gè)斐波那契數(shù)

思路:在上方函數(shù)的基礎(chǔ)上加上一個(gè)for循環(huán)即可

運(yùn)行效果?(格式化輸出):

請(qǐng)輸入數(shù)字:14
前14個(gè)斐波那契數(shù)為:
       1       1       2       3       5
       8      13      21      34      55
      89     144     233     377

實(shí)現(xiàn)代碼??????:

num = int(input('請(qǐng)輸入數(shù)字:'))


# 直接使用上面提到的fibonacci函數(shù)
def fib1(n):
    a, b = 1, 1
    for j in range(n - 1):
        a, b = b, a + b
    return a


if num <= 0:
    print('無(wú)效的輸入!')
else:
    print('前{}個(gè)斐波那契數(shù)為:'.format(num))
    for i in range(1, num + 1):
        print('{:8}'.format(fib1(i)), end='')    # 格式化輸出,每個(gè)結(jié)果占8位
        if i % 5 == 0:                           # 每輸出5個(gè),換一行
            print()                                     

2.2.3 求大于某個(gè)數(shù)的最小斐波那契數(shù)

運(yùn)行效果?:

請(qǐng)輸入數(shù)字:128
大于128的最小Fibonacci數(shù)是: 144
它是數(shù)列中的第12個(gè)數(shù)

實(shí)現(xiàn)代碼??????:

num = int(input('請(qǐng)輸入數(shù)字:'))


# 直接使用上面提到的fibonacci函數(shù)
def fib2(n):
    if n == 1 or n == 2:
        return 1
    else:
        return fib2(n - 1) + fib2(n - 2)


if num <= 0:
    print('無(wú)效的輸入!')
else:
    for i in range(1, num + 1):
        if fib2(i) > num:
            print('大于{}的最小斐波那契數(shù)是: {}\n它是數(shù)列中的第{}個(gè)數(shù)'.format(num, fib2(i), i))
            break

2.3 最大公約數(shù)、最小公倍數(shù)

2.3.1 最大公約數(shù)

最大公約數(shù)(Greatest Common Divisor)縮寫(xiě)為GCD
這里求最大公約數(shù)的方法為輾轉(zhuǎn)相除法

a, b = map(int, input('請(qǐng)輸入兩個(gè)數(shù)字,其間用空格隔開(kāi):').split())
big = max(a, b)                 # 比較兩個(gè)數(shù),使得big > small
small = min(a, b)
c = big % small                 # 將big作被除數(shù),small做除數(shù),相除后余數(shù)為c

while c != 0:
    big = small
    small = c
    c = big % small

print('{}和{}的最大公約數(shù)是:{}'.format(a, b, small))

2.3.2 最小公倍數(shù)

最小公倍數(shù)(Least Common Multiple)縮寫(xiě)為L(zhǎng)CM
求最小公倍數(shù)的方法:兩數(shù)之積除以最大公約數(shù)

lcm = int(a*b/small)
print('{}和{}的最小公倍數(shù)是:{}'.format(a, b, lcm))

2.4 折半查找(二分查找)

①. 題目??

本題要求采用折半查找的思想,每次搜索原來(lái)數(shù)據(jù)的一半,直到搜索成功或待搜索數(shù)據(jù)為空。

1.1 輸入格式

輸入一個(gè)列表A和查找的值B。

1.2 輸出格式

如果查找成功輸出數(shù)B在列表A中的位置,否則輸出查找不成功。

1.3 輸入樣例1

[19,23,46,49,65,78,98,101,125]
46

1.4 輸出樣例1

46 2

1.5 輸入樣例2

[19,23,46,49,65,78,98,101,125]
82

1.6 輸出樣例2

not find

②. 題解?

2.1 思路

使用eval()將輸入的值轉(zhuǎn)化為列表,使用sorted()將列表排序

關(guān)鍵:創(chuàng)建一個(gè)折半查找的函數(shù),傳入值為列表A與數(shù)字B

折半查找判斷方法:

將列表中間位置的值與查找值比較

  • 如果兩者相等,則查找成功;否則,利用中間位置的值將表分成前、后兩個(gè)子列表,
  • 如果中間位置記錄的值大于查找值,則進(jìn)一步查找一子列表;
  • 如果中間位置記錄的值小于查找值,則進(jìn)一步查找一子列表。

重復(fù)以上過(guò)程,直到找到滿(mǎn)足條件的記錄,使查找成功,或直到子表不存在為止,此時(shí)查找不成功。

2.2 代碼

a = sorted(eval(input()))       # 將輸入轉(zhuǎn)化為列表,并排序
b = int(input())


def find(ls, item):
    low = 0
    high = len(ls)
    while low < high:
        mid = int((low + high)/2)
        temp = ls[mid]
        if temp == item:
            return mid
        elif temp > item:
            high = mid - 1
        else:
            low = mid + 1
    return False


if find(a, b) is False:
    print('not find')
else:
    print('{} {}'.format(b, find(a, b)))

2.5 閏年

2.5.1 判斷閏年(核心)

判斷閏年相關(guān)知識(shí):

  • 四年一閏;百年不閏,四百年再閏
# 接收輸入
a = int(input('請(qǐng)輸入年份:'))


# 創(chuàng)建一個(gè)判斷閏年的函數(shù)
def is_leap_year(year):
    if year % 4 == 0:
        if year % 100 == 0:
            if year % 400 == 0:
                print('{}年是閏年'.format(year))        # format格式化輸出  | 四百年再閏
            else:
                print('{}年不是閏年'.format(year))   # 百年不閏
        else:
            print('{}年是閏年'.format(year))            # 四年一閏
    else:
        print('{}年不是閏年'.format(year))
     

# 調(diào)用函數(shù)
is_leap_year(a)

2.5.2 判斷某天是該年的第幾天

①. 題目??

輸入一個(gè)日期,打印出這一天是該年的第幾天

1.1 輸入樣例

請(qǐng)輸入日期,格式Y(jié)YYY MM DD:2020 04 17

1.2 輸出樣例

2020 04 17是2020年的第108天

②. 題解?

2.1 思路

  • 首先,此題的?核心?在于判斷閏年(判斷閏年方法:四年一閏;百年不閏,四百年再閏)
  • 其次,我們根據(jù)該年是否為閏年來(lái)創(chuàng)建兩個(gè)分別適用于平年和閏年的每月天數(shù)列表
  • 最后,將該月前面月份的天數(shù)與該月的天數(shù)相加即可“判斷一某天是該年的第幾天”

2.2 代碼

# 模塊一:接受輸入的日期,切片存儲(chǔ)
date = input('請(qǐng)輸入日期,格式Y(jié)YYY MM DD:')
year = int(date[0:4])                   # 切片后存儲(chǔ)
month = int(date[5:7])
day = int(date[8:])
# 上方代碼可簡(jiǎn)化為
# year, month, day = map(int, input().split())


# 模塊二:判斷閏年
def is_leap_year(year):
    if year % 4 == 0:
        if year % 100 == 0:
            if year % 400 == 0:
                return True             # 四百年再閏
            return False                # 百年不閏
        return True                     # 四年一閏
    return False


# 模塊三:閏年/平年每月天數(shù)列表
if is_leap_year(year) is True:
    month_list = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
else:
    month_list = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]


# 模塊四:判斷輸入的月份,加上之前的天數(shù)
days = 0                                # 某月之前月份包含的天數(shù)
for i in range(month - 1):
    days += month_list[i]
total = days + day                      # 總天數(shù)


# 模塊五:格式化輸出
print('{}是{}年的第{}天'.format(date, year, total))

2.6 錢(qián)??

2.6.1 發(fā)紅包

①. 題目??

使用random()模擬10次發(fā)紅包的情況。

1.1 輸入樣例

請(qǐng)輸入紅包總金額:100
請(qǐng)輸入紅包總數(shù)量:8

1.2 輸出樣例

[11, 34, 16, 14, 2, 16, 2, 5]
[65, 26, 2, 1, 1, 2, 1, 2]
[30, 61, 3, 2, 1, 1, 1, 1]
[70, 10, 12, 1, 3, 1, 1, 2]
[14, 43, 31, 2, 7, 1, 1, 1]
[64, 11, 18, 3, 1, 1, 1, 1]
[91, 3, 1, 1, 1, 1, 1, 1]
[27, 24, 14, 2, 21, 4, 2, 6]
[64, 11, 6, 2, 14, 1, 1, 1]
[36, 19, 15, 12, 1, 8, 2, 7]

②. 題解?

2.1 代碼

import random

a = int(input('請(qǐng)輸入紅包總金額:'))
b = int(input('請(qǐng)輸入紅包總數(shù)量:'))


def dis_lucky_money(total, num):
    pack = []                                                           # 以列表形式存儲(chǔ)分配的紅包金額
    already = 0                                                         # 已經(jīng)分配的金額

    # 前num-1次的分配情況
    for j in range(1, num):
        least_remain = num - j                                          # 后幾個(gè)紅包中至少含有的總金額
        money = random.randint(1, (total - already) - least_remain)     # randint取值范圍包含首尾 <區(qū)別于range()>
        pack.append(money)
        already += money

    pack.append(total - already)                                        # 將剩余的錢(qián)作為最后一個(gè)紅包,添加至紅包分配列表
    print(pack)


# 隨機(jī)生成10次
for i in range(10):
    dis_lucky_money(a, b)

2.6.2 換硬幣

①. 題目??

將一筆零錢(qián)??換成5分、2分和1分的硬幣,要求每種硬幣至少有一枚,有幾種不同的換法?

1.1 輸入格式

輸入在一行中給出待換的零錢(qián)數(shù)額x∈(8,100)。

1.2 輸出格式

要求按5分、2分和1分硬幣的數(shù)量依次從大到小的順序,輸出各種換法。
每行輸出一種換法,格式為:“fen5:5分硬幣數(shù)量, fen2:2分硬幣數(shù)量, fen1:1分硬幣數(shù)量, total:硬幣總數(shù)量”。
最后一行輸出“count = 換法個(gè)數(shù)”。

1.3 輸入樣例

13

1.4 輸出樣例

fen5:2, fen2:1, fen1:1, total:4
fen5:1, fen2:3, fen1:2, total:6
fen5:1, fen2:2, fen1:4, total:7
fen5:1, fen2:1, fen1:6, total:8
count = 4

②. 題解?

2.1 思路

換錢(qián)??時(shí),先確定大面值的數(shù)量,再以此確定較小面值的數(shù)量

2.2 代碼

x = int(input())

fen1 = 1
fen2 = 2
fen5 = 5
total = 0
count = 0

for i in range(x//5, 0, -1):                # '//'為整除運(yùn)算
    for j in range(x//2, 0, -1):
        for k in range(x, 0, -1):
            if fen5*i + fen2*j + fen1*k == x:
                total = i + j + k
                count += 1
                print('fen5:{}, fen2:{}, fen1:{}, total:{}'.format(i, j, k, total))

print('count =', count)

2.7 撲克牌??

2.7.1 普通發(fā)牌

①. 題目??

從鍵盤(pán)輸入一個(gè)整數(shù)作為隨機(jī)種子,隨機(jī)生成一副撲克牌(去掉大小王),循環(huán)分給4位牌手,每人5張牌(第1、5、9、13、17張牌給第一個(gè)玩家,第2、6、10、14、18給第二個(gè)玩家...以此類(lèi)推)并輸出。

1.1 輸出樣例

4
?Q   ?10  ?A   ?9   ?4   ?K   ?3   ?Q   ?4   ?5   ?8   ?A   ?J   
?K   ?2   ?K   ?J   ?3   ?7   ?2   ?7   ?6   ?4   ?Q   ?10  ?3   
?8   ?A   ?A   ?6   ?9   ?J   ?Q   ?5   ?J   ?9   ?8   ?2   ?4   
?6   ?10  ?9   ?2   ?5   ?6   ?10  ?5   ?K   ?8   ?7   ?7   ?3   
第1個(gè)玩家的牌是:?Q, ?4, ?4, ?J, ?J
第2個(gè)玩家的牌是:?10, ?K, ?5, ?K, ?3
第3個(gè)玩家的牌是:?A, ?3, ?8, ?2, ?7
第4個(gè)玩家的牌是:?9, ?Q, ?A, ?K, ?2

②. 題解?

2.1 知識(shí)儲(chǔ)備

  1. random.seed():獲取某種特定生成的隨機(jī)數(shù)
    當(dāng)seed()無(wú)參數(shù)時(shí),每次生成的隨機(jī)數(shù)不同,
    當(dāng)seed()有參數(shù)時(shí),若參數(shù)相同,則每次生成的隨機(jī)數(shù)相同;若參數(shù)不同,則生成的隨機(jī)數(shù)也不同
import random

ls = [1, 2, 3, 4, 5, 6, 7, 8]

for i in range(8):
    random.seed(4)                  # 試著改變seed()中的數(shù)或者注釋掉這一行,看看輸出的變化
    print(random.randint(1, 10))    # randint(a, b)隨機(jī)生成[a, b]間的整數(shù)

# 注意??:randint與range取值范圍的區(qū)別。前者能取右側(cè)的值,后者不能
  1. random.shuffle():將一個(gè)序列(列表、字符串或元組)的順序打亂
# 示例
import random

mylist = ["apple", "banana", "cherry"]
random.shuffle(mylist)

print(mylist)

2.2 代碼

import random


# 生成一副不含大小王的撲克牌序列
def create(suit, d):
    ls = []
    for i in range(4):
        for j in range(13):
            temp = suit[i] + d[j]
            ls.append(temp)
    return ls


# 隨機(jī)洗牌
def shufflecard(pokers):
    random.shuffle(pokers)
    return pokers


# 發(fā)5張牌給一個(gè)玩家并將發(fā)給該玩家的牌輸出
def deal(pokers, n):
    ls = []
    for i in range(n - 1, n + 16, 4):
        ls.append(pokers[i])
    print('第{}個(gè)玩家的牌是:{}'.format(n, ', '.join(ls)))


n = int(input())

suit = ['?', '?', '?', '?']
d = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
random.seed(n)
poker = create(suit, d)
poker = shufflecard(poker)

for i in range(52):
    print('{:4}'.format(poker[i]), end=' ')     # 格式化輸出洗牌后的牌
    if i % 13 == 12:
        print()                                 # 換行
for i in range(1, 5):
    deal(poker, i)

2.7.2 用類(lèi)發(fā)牌

①. 題目??

編寫(xiě)程序, 4名牌手打牌,計(jì)算機(jī)隨機(jī)將52張牌(不含大小鬼)發(fā)給4名牌手,在屏幕上顯示每位牌手的牌。

提示:
設(shè)計(jì)出3個(gè)類(lèi):Card類(lèi)、Hand類(lèi)和Poke類(lèi)。
Card類(lèi)代表一張牌,其中FaceNum字段指出是牌面數(shù)字1~13,Suit字段指出的是花色,值“梅”為梅花,“方”為方塊,“紅”為紅心,“黑”為黑桃。
Hand類(lèi)代表一手牌,可以認(rèn)為是一位牌手手里的牌,其中cards列表變量存儲(chǔ)牌手手里的牌??梢栽黾优?、清空手里的牌、把一張牌給別的牌手。
Poke類(lèi)代表一副牌,可以把一副牌看作是有52張牌的牌手,所以繼承Hand類(lèi)。

1.1 輸出樣例

This is a module with classes for playing cards.
牌手 1:紅桃6    黑桃6 梅花A 方片6 黑桃2 梅花10    紅桃3 方片4 方片10    黑桃J 紅桃Q 紅桃10    紅桃8 
牌手 2:梅花J    梅花9 紅桃7 紅桃2 方片K 黑桃K 梅花3 方片7 黑桃Q 黑桃10    梅花Q 梅花8 黑桃7 
牌手 3:梅花2    方片A 黑桃3 方片9 黑桃4 紅桃K 紅桃J 梅花7 紅桃4 方片2 梅花4 梅花6 紅桃5 
牌手 4:黑桃5    紅桃9 方片8 梅花5 方片J 黑桃A 梅花K 方片5 黑桃9 方片3 黑桃8 方片Q 紅桃A

②. 題解?

2.1 代碼

# Card類(lèi):一張牌
class Card:
    """A playing card.card"""
    RANKS = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
    SUITS = ['梅花', '方片', '紅桃', '黑桃']

    def __init__(self, rank, suit, face_up=True):
        self.rank = rank                # 牌面數(shù)字1~13
        self.suit = suit                # 花色
        self.is_face_up = face_up       # 是否顯示牌的正面,True為正面,F(xiàn)alse為反面

    def __str__(self):                  # 重寫(xiě)print()方法,打印一張牌的信息
        if self.is_face_up:
            rep = self.suit + self.rank
        else:
            rep = 'XX'
        return rep

    def pic_order(self):                # 牌的順序號(hào)
        if self.rank == 'A':
            FaceNum = 1
        elif self.rank == 'J':
            FaceNum = 11
        elif self.rank == 'Q':
            FaceNum = 12
        elif self.rank == 'K':
            FaceNum = 13
        else:
            FaceNum = int(self.rank)
        if self.suit == '梅花':
            Suit = 1
        elif self.suit == '方片':
            Suit = 2
        elif self.suit == '紅桃':
            Suit = 3
        else:
            Suit = 4
        return (Suit - 1) * 13 + FaceNum

    def flip(self):                     # 翻牌方法
        self.is_face_up = not self.is_face_up


# Hand類(lèi):一手牌
class Hand:
    """A hand of playing cards  Hand"""

    def __init__(self):
        self.cards = []                 # cards列表變量存儲(chǔ)牌手手里的牌

    def __str__(self):                  # 重寫(xiě)print()方法,打印出牌手的所有牌
        if self.cards:
            rep = ''
            for card in self.cards:
                rep += str(card) + '\t'
        else:
            rep = '無(wú)牌'
        return rep

    def clear(self):                    # 清空手里的牌
        self.cards = []

    def add(self, card):                # 增加手里的牌
        self.cards.append(card)

    def give(self, card, other_hand):   # 把一張牌給其他選手
        self.cards.remove(card)
        other_hand.add(card)
        # other_hand.append(card)       # 上面兩行可以用這一行代替


# Poke類(lèi):一副牌
# 繼承Hand類(lèi)
class Poke(Hand):
    """Poke類(lèi)代表一副牌,可以看做是有52張牌的牌手,所以繼承Hand類(lèi)。由于其中cards列表變量要存儲(chǔ)52張牌
    而且要發(fā)牌,洗牌,所以增加方法如下方法:"""

    def populate(self):                 # 生成一副牌
        for suit in Card.SUITS:
            for rank in Card.RANKS:
                self.add(Card(rank, suit))

    def shuffle(self):                  # 洗牌
        import random
        random.shuffle(self.cards)      # 打亂牌的順序

    def deal(self, hands, per_hand=13):  # 將牌發(fā)給玩家,每人默認(rèn)13張牌
        for rounds in range(per_hand):
            for hand in hands:
                if self.cards:
                    top_card = self.cards[0]
                    self.cards.remove(top_card)
                    hand.add(top_card)
                    # self.give(top_card,hand)  #上兩句可以用此句替換
                else:
                    print('不能繼續(xù)發(fā)牌了,牌已經(jīng)發(fā)完了!')


if __name__ == "__main__":
    print('This is a module with classes for playing cards.')
    players = [Hand(), Hand(), Hand(), Hand()]
    poke1 = Poke()
    poke1.populate()                    # 生成一副牌
    poke1.shuffle()                     # 洗牌
    poke1.deal(players, 13)             # 發(fā)給每人13張牌
    n = 1
    for hand in players:
        print('牌手', n, end=':')
        print(hand)
        n = n + 1

一路看到這里,相信你的Python考試應(yīng)該已經(jīng)增加了幾分勝算????

如果喜歡本文請(qǐng)不吝點(diǎn)贊????,如果愛(ài)上本文請(qǐng)留下評(píng)論~

如果既不想點(diǎn)贊又不想評(píng)論...

那么去聽(tīng)首我原創(chuàng)的歌曲也好鴨??


參考資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容