Python的函數、字符串、數據結構及面向對象

函數def

定義函數

1,我們可以把程序中相對獨立的功能模塊抽取出來

這樣做的好處:一是減少重複代碼的編寫,二是將來可以重複的使用這些功能模塊

2,Python中的函數就是代表了這樣的功能模塊

y = f(x): f是函數名,x是自變量,y是因變量

定義一個函數時括號內的自變量可以是0個也可以是多個

Python中定義函數官方建議開頭和結尾空出兩行

注意:如果要重命名函數,選中函數名右鍵重構重命名,不要手動一個一個去改名,這樣既浪費時間又有可能漏改!!!

       在使用模塊時容易出現命名衝突如果從不同模塊導入了兩個重名的函數,系統會自動屏蔽掉一個;其中後定義的那一個生效,
       它會自動覆蓋掉它之前的那一個函數;也可以通過使用一個函數後再次導入另一個函數。

       我們也可以給自己定義的函數用別名取代imort ... as ...       在導入一個模塊時如果名字太長想改短,也可以用別名import ... as ...

       在導入一個函數時Ctrl + 左鍵可以看到該函數的定義
  • 定義一個求階乘的函數 - 將求階乘的功能抽取出來放到函數中
def f(x):
    # 文檔註釋:三引號開頭,三引號結尾,在使用時對函數按快捷鍵Ctrl + q可以看到這個註釋
    '''
    計算階乘
    :param x:一個非負整數
    :return: 階乘
    '''
    y = 1
    for num in range(1, x + 1):
        y *= x
    return y

m = int(input('m = '))
n = int(input('n = '))
# 當需要計算階乘的時候不用再寫循環,而是直接調用已經定義好的函數
print(f(m - n))
print(f(m) // f(n) // f(m - n))
  • 定義搖兩顆色子的函數,它會返回搖出的點數
def roll_two_dice():
    face1 = randint(1, 6)
    face2 = randint(1, 6)
    return face1 + face2

# 定義變量中的n = 2表示沒有給變量的時候默認值爲2,當代碼中用戶輸入變量的時候函數的變量就是用戶輸入的值。
# 定義變量默認值的時候等號兩邊不建議加空格,在使用這個函數時變量等號兩邊也不加空格
def roll_dice(n=2):
    total = 0
    for _ in range(n):
        total += randint(1,6)
    return total
  • 調用某個文件中定義的一個函數
import is_prime().xxx

from xxx import is_prime()

# 這種後面加*的表示導入xxx中所有的函數
from xxx import *

# 計算最大公約數的函數
def gcd(x, y):
    # Python中的三元條件運算,if條件成立取前面的值,否則取後面的值
    (x, y) = (y, x) if x > y else (x , y)
    # 在range循環中如果要讓循環倒着跑,可以把步長設置成 - 1
    for factor in range(x, 0 ,-1):
        if x % factor == 0 and y % factor == 0:
            return factor

# 計算最小公倍數的函數
def lcm(x, y):
    return x * y // gcd(x, y)

# 通過下面的if條件可以在導入模塊時不去執行原模文件下除函數外的代碼
# __name__是Python中一個隱含的變量它代表了模塊的名字
# 只有被Python解釋器直接執行的模塊的名字纔是__main__
if __name__ == '__main__':
    number = int(input('number = '))
    print(is_prime(number))
  • 可變參數 - 在不確定要輸入的參數個數時,定義 *args,參數可以有0或任意多個
def add(*args):
    total = 0
    for value in args:
        total += value
    return total

print(add(5,6,7))
  • 判斷一個數是不是迴文數
def is_palindrome(num):
    '''
    判斷一個數是不是迴文數
    :param num: 一個非負整數
    :return: 是迴文數返回True否則返回False
    '''
    temp = num
    total = 0
    while temp > 0:
        total = total * 10 + temp % 10
        temp //= 10
    return total == num

number = int(input('請輸入一個非負整數:'))

# and和pr運算符都是帶短路功能的運算符
# 如果and左邊的表達式是False那麼右邊的表達式被短路(不執行)
# 如果or左邊的表達式是True那麼右邊的表達式被短路
# 所以左右兩邊的表達式放置的順序可能會對程序的執行效率產生明顯的影響。通常把運算量小的放左邊!
if is_palindrome(number) and is_prime(number):
    print('%d是迴文素數' % number)
else:
    print('%d不是迴文素數' % number)

作用域

Python中搜索一個變量的方式是從局部作用域到嵌套作用域再到全局作用域再到內置作用域

 Local - Enclosed - Global - 內置作用域 (L - E - G - B)

如果想改變搜索範圍,可以使用gloabl和nonlocal關鍵字

實際開發時一定要儘可能減少全局變量的使用!遵循迪米特法則:儘量不要讓模塊之間產生關聯

a = 100
b = 'good'
# gloable variable在函數外面定義的a是一個全局變量

def foo():
    # local variable函數內的局部變量,離開foo函數變量a是無法訪問的
    # 如果函數內想要調用全局變量,就在變量前加上global
    # 這裏調用全局變量,會影響到後面全局變量的值
    global a
    a = 200
    b = 'hello'

    def bar():
        # 這裏如果想要搜索外部的b,用嵌套作用域nonlocal
        # nonlocal b
        b = hello
        print(a)
        print(b)
    bar(b)
    a = 200
    print(a)
  • 定義一個函數求階乘
# 這裏可以使用遞歸算法
# 使用遞歸的條件1:收斂條件 - 讓遞歸在有限的次數內完成或者進行回溯
#                  如果遞歸無法在有限次數內收斂就有可能導致RecursionError
#               2:遞歸公式
# 函數可以自己調用自己,但是不能無休止的調用
def f(n):
    if n == 0 or n == 1:
        return 1
    return n * f(n - 1)

if __name__ == '__main__':
    # 在進入函數調用之前要保存當前的執行現場
    # 函數的執行現場是保存在一種稱爲棧(stack)的內存空間上
    # 棧是一種先進後出(FILO)的存儲結構
    print(f(65))
  • 小女孩走10級臺階,可以一次走一階/兩階/三階,有多少種走法
def walk(n):
    if n < 0:
        return 0
    elif n == 0:
        return 1
    return walk(n - 1) + walk(n - 2) + walk(n - 3)

if __name__ == '__mian__':
    mian()

字符串str

def main():
    # 查help也可以這樣用
    print(help(''.capitalize))
    # 不變字符串
    str1 = 'hello, world!'
    print(len(str1))
    print(str1.capitalize())
    print(str1.upper())
    print(str1)
    print(str1.find('or'))
    print(str1.find('shit'))
    print(str1.index('or'))
    # 用index如果查找沒有結果的話會報錯停止程序運行
    print(str1.startswith('He'))
    print(str1.startswith('hel'))
    print(str1.endswith('!'))
    print(str1.center(50, '*'))
    print(str1.rjust(50, ' '))

    str2 = 'abc123456'
    # 字符串切片操作
    print(str2[2])
    print(str2[2:5])
    print(str2[2::2])
    print(str2[:])
    print(str2[::2])
    print(str2[::-1])
    print(str2[-3:-1])
    print(str2[-1:-3:-1])
    # 檢查字符串是否由數字構成
    print(str2.isdigit())
    # 檢查字符串是否以字母構成
    print(str2.isalpha())
    # 檢查字符串是否以數字和字母構成
    print(str2.isalnum())

    str3 = '   dsagoihsdlkj   '
    print(str3)
    # 獲得字符串修剪左右兩側空格的拷貝
    print(str3.strip())


if __name__ == '__main__':
    main()
  • 設計一個函數,給一個文件名,把後綴名提取出來
# abc.  .abc
def get_suffix(filename,has_dot=False):
    '''
    獲取文件名的後綴名
    :param filename: 文件名
    :param has_dot: 後綴名是否帶.
    :return: 文件名的後綴
    '''
    pos = filename.rfind('.')
    if 0 < pos < len(filename) - 1:
        index = pos if has_dot else pos + 1
        return filename[index:]
    else:
        return ''

if __name__ == '__main__':
    print(get_suffix('awdsd.exe'))

列表list

有了列表(容器)我們可以使用1個變量來保存多個數據,更爲重要的是我們可以使用循環對列表中保存的數據進行操作。

列表生成表達式語法創建列表容器,用這種語法創建列表之後元素已經準備就緒,所以需要消耗較多的內存空間。

列表生成器得到的不是一個列表,而是一個生成器對象,通過生成器可以獲取到數據,它不佔用額外的空間存儲數據,每次需要數據的時候就通過內部的運算得到數據,但這需要花費時間。

def main():
    list1 = [1, 2, 3, 4, 5]
    print(list1)
    list2 = ['hello','world','Python'] 
    print(list2)
    print(len(list1))
    # 下標運算
    print(list1[0])
    print(list1[4])
    print(list1[-1])
    print(list1[-3])
    list1[2] = 300
    print(list1)
    # 添加元素
    list1.append(200)
    list1.insert(1, 400)
    list1 += [1000, 2000]
    print(list1)
    print(len(list1))
    # 刪除元素
    list1.remove(3)
    if 1234 in list1:
        list1.remove(1234)
    del list1[0]
    print(list1)
    # 清空列表元素
    list1.clear()
    print(list1)

    list3= ['sfjoiej', 'askg', 'beoihg', 'wjwoieg']
    list3 += ['jasdkn', 'pass', 'ewvgh']
    # 循環遍歷列表元素
    for list in list3:
        print(list.title(), end=' ')
    print()
    # 列表切片
    list4 = list3[1:4]
    print(list4)
    list5 = list3[:]
    print(list5)
    list6 = list3[-3:-1]
    print(list6)
    # 可以通過反向切片操作來獲得倒轉後的列表的拷貝
    list7 = list3[::-1]
    print(list7)

    # 列表排序
    f = ['blue', 'red', 'orange','icecream', 'pepsi']
    # Python內置的排序方法默認都是排升序(從小到大)
    # 如果希望排列成降序,可以通過reverse參數來指定
    # Python中的函數幾乎都是沒有副作用的函數
    # 調用函數之後不會影響傳入的參數
    f2 = sorted(f, reverse = True)
    print(f)
    print(f2)
    f.sort(reverse=True)
    print(f)
    f.reverse()
    # f3是直接在f上進行反轉,如果不加f3 = ,返回的是把f裏元素反轉後f的結果
    f3 = reversed(f)
    print(f3)
    # 通過輸入關鍵字類型來進行排序
    f4 = sorted(f, key=str_len, reverse=True)
    print(f4)

if __name__ == '__main__':
    main()
import sys

def main():
    f = (x ** 2 for x in range(1, 100))
    print(sys.getsizeof(f))
    for val in f:
        print(val,end = '\t')

if __name__ == '__main__':
    main()
def f(*args):
    total = 0
    for val in args:
        total += val
    return total

# 把一個列表當成可變參數傳入函數,不能直接print(f(my_list))需要用 *args 把列表拆散傳入函數
my_list = [1,2,3,4,5]
print(f(*my_list))
# 枚舉enumerate,也是一種數據類型,這種數據類型只包含自定義的特定數據,它是一組有共同特性的數據的集合
def main():
    f = [100, 200, 300]
    for index, val in enumerate(f):
        print(index, ':', val)

    # CRUD操作 Create Read Update Delate
    f.append(123)
    f.insert(1,300)
    print(f)
    if 300 in f:
        f.remove(300)
    # f.clear()
    del f[3]
    print(f)
    # print(f.index(100, 3, 5))
    # pop:移除列表中的一個元素(默認最後一個元素),並且返回該元素的值
    print(f.pop(1))
    print(f)

if __name__ == '__main__':
    main()
  • 生成一個斐波拉切數列 fn = f(n-1)+ f(n-2)
def main(n=2):
    f = [1, 1]
    print(f)
    for index in range(2, n):
        val = f[index - 1] + f[index - 2]
        f.append(val)
        print(f)

if __name__ == '__main__':
    main()
  • 設計一個函數,從傳入的列表中找出第二大的元素(要求只能使用一次循環)
def second_max(x):
    # 元組
    # 元組是隻讀的,不能寫
    (m1,m2) = (x[0], x[1]) if x[0] > x[1] else (x[1], x[0])
    for index in range(2, len(x)):
        if x[index] > m1:
            m2 = m1
            m1 = x[index]
        elif x[index] > m2:
            m2 = x[index]
    return m2

def main():
    my_list = [23,554,43,56,87,355,76]
    print(second_max(my_list))

if __name__ == '__main__':
    main()
  • 有30個人坐船出海,途中船壞了只能承載15人,於是這30人圍城一圈,從第一個人開始報數,報到9的人就丟進海里,下一個人重新開始報數,以此類推,結果 最後船上剩餘的人全是基督徒,問之前這些人站的位置?
# 這裏可以用約瑟夫環來解決這個問題
def main():
    persons = [True] * 30
    counter = 0
    index = 0
    number = 0
    while counter < 15:
        if persons[index]:
            number += 1
            if number == 9:
                persons[index] = False
                counter += 1
                number = 0
        index += 1
        # if index == 30:
        #     index = 0
        index = index % 30
    for person in persons:
        print('基' if person else '非',end='')


if __name__ == '__main__':
    main()

元組tuple

元組與列表類似,不同的在於元組中的元素不可修改,也就是說元組是隻讀的

集合

列表是有順序的,能用小標來取元素

集合是離散存儲數據,沒有順序,無法用下標來取元素,可以用遍歷pop,但是取出來的元素不確定

def main():
    set1 = {1,1,2,2,3,3}
    set1.add(4)
    set1.add(5)
     # 集合中輸入重複的元素輸出時只有一個,因爲集合中不允許出現重複的元素
    print(set1) # {1,2,3,4,5}
    set2 = {1,2,3,4,5,7,9}
    print(set2)
    set3 = set1.intersection(set2)
    print(set3)
    set4 = set1.union(set2)
    print(set4)
    set5 = set1 & set2
    print(set5)
    set6 = set1 | set2
    print(set6)
    set7 = set2 - set1
    print(set7)
    print(set1 <= set2)
    set2 = {'hello','good','banana','zoo','puthon','apple'}
    print(len(set12))
    x = sorted(set2)
    print(type(x))
    list1 = list(set2)
    print(list1)
    list2 = [1,2,3,1,2,4]
    set2 = set(list2)
    print(set2)
    tuple = (1,1,2,3,4,4)
    list3 = list(tuple)
    print(list3)
    set3 = set(tuple)

if __name__ == '__main__':
    main()
  • 定義一個函數,生成一個成績列表
def main():
    names = ['關羽','張飛','趙雲','馬超','貂蟬']
    subjects = ['語文','數學','python']
    # table = [[0] * len(subjects) * len(names)]這個方式複製的是5個列表的元素地址,輸出結果5個列表會完全一樣
    # 下面的複製列表就不會出現這樣的問題
    table = [[0] * len(subjects) for _ in range(len(names))]
    for x,name in enumerate(names):
        print('請輸入%s的成績:' % name)
        for y,subject in enumerate(subjects):
            score = int(input('%s:' % subject))
            table[x][y] = score
    print(table)

if __name__ == '__main__':
    main()

字典dict

字典可以存儲任意類型對象,字典的每個元素都是由一個鍵和一個值組成的“鍵值對”,鍵和值通過冒號分開。

def main():
    dict1 = {'name':'趙信','age':25,'gender':True}
    print(dict1['name'])
    print(dict1['age'])
    print(dict1['gender'])
    dict1['name'] = '一葉知秋'
    print(dict1)
    # dict1 += {'tel':'123445678'}
    dict1.update(height=178, fav=['吃,玩'])
    print(dict1)
    print(dict1.pop('age'))
    print(dict1.popitem())
    dict1['name'] = None

    for x in dict1:
        print(x,'--->',dict1[x])

if __name__ == '__main__':
    main()

面向對象

對象特徵:1,一切都是對象

      2,對象都有屬性(靜態特徵)和行爲(動態特徵)

      3,每個對象都是獨一無二的

      4,對象一定會歸屬到某個類(類型/類別),類是對象的藍圖和模板

         類是抽象的,對象是具體的

step 1,定義類

   類是對象的藍圖和模板,有了類就可以創建對象

   定義類需要做兩件事:數據抽象和行爲抽象

   數據抽象 - 抽取對象共同的靜態特徵(找名詞) - 屬性

   行爲對象 - 抽取對象共同的動態特徵(找動詞) - 方法

   定義類的關鍵字 - class - 類名(每個單詞首字母大寫)

step 2,調用構造方法創建對象

step 3,給對象發消息

注意 自己定義的類每個單詞首字母都要大寫

      寫在類裏面的def叫方法,方法與方法之間至少要留一個空行

      我們定義一個類實際上是把數據和操作數據的函數綁定到一起,形成一個邏輯上的整體,這個整體就叫對象,
      而且將來任何時候想使用這種對象時直接複用這個類就可以了
# object是Python內置的一個類
class Student(object):

    # init初始化/設定默認值
    # __init__構造方法(構造器/構造子 - constructor)
    # 調用改方法的時候不是直接使用方法的名字,而是使用類的名字
    def __init__(self,name,age):
        # 給對象綁定屬性
        self.name = name
        self.age = age

    # 我們定義一個方法就代表對象可以接收這個消息
    # 對象的方法的第一個參數都是統一寫成self
    # 它代表了接收消息的對象 - 對象.消息(參數)
    def study(self,course):
        # self.表示接收消息的對象
        print('%s正在學習%s' % (self.name, course))

    def watch_av(self):
        if self.age >= 18:
            print('%s正在觀看島國愛情動作片' % self.name)
        else:
            print('%s,我們推薦你觀看《天線寶寶》' % self.name)


def main():
    # 調用構造方法創建學生對象
    # 實際上調用的是Student
    stu1 = Student('李牧',40)
    # 給對象發消息
    # 通過給對象發消息,讓對象完成某些工作,就可實現程序的功能
    # 解決任何問題都是通過讓對象去做事情來解決的
    stu1.study('Python程序設計')
    stu2 = Student('鍾嶽',17)
    stu2.study('HTML網頁設計')
    stu2.watch_av()


if __name__ == '__main__':
    main()
  • 寫一個類,顯示數字時鐘
class Clock(object):
    '''時鐘'''
    def __init__(self, hour = 0, minute = 0, second = 0):
        # 構造器...
        self._hour = hour
        self._minute = minute
        self._second = second

    def run(self):
        ''' 走字'''
        self._second += 1
        if self._second == 60:
            self._second = 0
            self._minute += 1
            if self._minute == 60:
                self._minute = 0
                self._hour += 1
                if self._hour == 24:
                    self._hour = 0

    # 這是一個特殊方法
    # 下面的方法可以獲得對象的字符創表示形式
    # 當我們用print打印對象時會自動調用該方法
    # def __str__(self):
    def show(self):
        '''
        顯示時間
        :return:時間
        '''
        return '%02d:%02d:%02d' % (self._hour, self._minute,self._second)

from time import sleep

def main():
    clock = Clock(1,34,12)
    while True:
        print(clock.show())
        sleep(1)
        # clock.run()

if __name__ == '__main__':
    main()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章