【编程小白的第一本python入门书】 --学习笔记

前言

一直都想学Python,之前粗略看过【Python学习手册(第4版)】,现在基本忘光了(毕竟没怎么用它来写代码)。重新翻开这本书时感觉有些老了,于是随便找了本先看着,快要读完时发现了宝藏——【Python语言程序设计】(据说是斯坦福大学的教材),等这本书看完后再拿那本书巩固、补充好了。

初识变量

变量

用法:变量 = 赋值内容

answer = 42

print()

用法:print(内容)

print(answer)
print('hello world!')

文件的写入方法

file = open('D:/PythonCode/file.txt', 'w')
file.write('hello world')

字符串

用法

可用单引号、双引号或三个引号(连接换行的文本)来表示

连接

what_he_does = ' plays '
his_instrument = 'guitar'
his_name = 'Robert Johnson'
artist_intro = his_name + what_he_does + his_instrument

print(artist_intro)

类型转换

num = 1
string = '1'
num2 = int(string)

print(num + num2)

乘法

words = 'words' * 3
print(words)
word = 'a loooooong word'
num = 12;
string = 'bang!'
total = string * (len(word) - num)
print(total)

分片与索引

[x:y] --> [x,y)

[x:] --> [x,len]

[:x] --> [0, x)

正向索引:从前往后字符下标依次为0、1、…、len-1

反向索引:从后往前字符下标依次为-1、-2、…、-len

字符串的方法

search = '168'
num_a = '1386-168-0006'
num_b = '1681-222-0006'

print(search + ' is at ' + str(num_a.find(search)) + ' to ' + str(num_a.find(search) + len(search)) + ' of num_a')
print(search + ' is at ' + str(num_b.find(search)) + ' to ' + str(num_b.find(search) + len(search)) + ' of num_b')

字符串格式化符

print('{} a word she can get what she {} for.'.format('With', 'came'))
print('{preposition} a word she can get what she {verb} for'.format(preposition = 'With', verb = 'came'))
print('{0} a word she can get what she {1} for.'.format('With', 'came'))

函数

内建函数

“自带”的函数,可参考:https://docs.python.org/3/library/functions.html

自定义函数

  1. 定义

    def function(arg1, arg2):    # 不要漏掉冒号
        return 'Something'
  2. 举例(摄氏度转化为华氏度)

    def fahrenheit_converter(C):
        fahrenheit = C * 9 / 5 + 32
        return str(fahrenheit) + '°F'

传递参数与参数类型

  1. 位置参数:将数值传到对应位置上,如function(1, 2)。
  2. 关键词参数:通过在参数列表里填写对应变量名 = 数值,如function(arg1 = 1, arg2 = 2)。
  3. 注意:通过关键词参数传参时位置可不用对应;通过位置参数传参时位置需对应。

简单函数设计

  1. 在桌面写入的文件名称和内容的函数

    def text_create(name, msg):
        desktop_path = 'C://Users/a/Desktop/'
        full_path = desktop_path + name + '.txt' # 文件路径
        file = open(full_path, 'w')  # 'w'代表写入模式,如果没有就在该路径创建一个有该名称文本,有则追加覆盖文本内容
        file.write(msg)  # 写入传入的参数msg,即内容
        file.close() # 关闭文本
        print('Done')
    
    text_create('hello', 'hello world')
  2. 敏感词替换器

    def text_filter(word, censored_word = 'lame', changed_word = 'Awesome'):
        return word.replace(censored_word, changed_word)
    print(text_filter('Python is lame!'))
  3. 在桌面上创建一个文本可以在其中输入文字,如果信息中有敏感词将默认过滤后写入文件。

    def text_create(name, msg):
        desktop_path = 'C://Users/a/Desktop/'
        full_path = desktop_path + name + '.txt'
        file = open(full_path, 'w')
        file.write(msg)
        file.close()
        print('Done')
    
    def text_filter(word, censored_word = 'lame', changed_word = 'Awesome'):
        return word.replace(censored_word, changed_word)
    
    def censored_text_create(name, msg):
        clean_msg = text_filter(msg)
        text_create(name, clean_msg)
    
    censored_text_create('try', 'lame!lame!lame!')

判断

逻辑控制

  1. 逻辑判断:True、False

  2. 比较运算:>、<、>=、<=、==、!=

  3. 成员运算符与身份运算符

    • in:表示归属关系的布尔运算符。

      判断一个元素是否在列表/字典中/元组/集合…中。

    • is:表示身份鉴别的布尔运算符。

      ==的区别:is比较的是地址,==比较的是内容。

  4. 布尔运算符:not、and、or

条件控制

  1. 格式

    if condition:
        do something
    else:
        do something
  2. 举例

    def account_login():
        password = input('Passowrd:')
        if password == '12345':
            print('Login success!')
        else:
            print('Wrong password or invalid input!')
            account_login()
    
    account_login()
  3. else if的写法

    if condition:
        do something
    elif condition:
        do something
    else:
        do somehing
  4. 练习

    password_list = ['*#*#', '12345']
    
    def account_login():
        password = input('Passowrd:')
        password_correct = password == password_list[-1]
        password_reset = password == password_list[0]
        if password_correct:
            print('Login success!')
        elif password_reset:
            new_password = input('Enter a new password:')
            password_list.append(new_password)
            print('Your password has changed successfully!')
            account_login()
        else:
            print('Wrong password or invalid input!')
            account_login()
    
    account_login()

循环

for循环

  1. 格式:

    for item in iterable:
        do something
  2. 例子:

    for every_letter in 'Hello world':
        print(every_letter)
    for num in range(1, 11):
        print(str(num) + ' + 1 =', num + 1)
    songslist = ['Holy Diver', 'Thunderstruck', 'Rebel Rebel']
    
    for song in songslist:
        if song == 'Holy Diver':
            print(song, '- Dio')
        elif song == 'Thunderstruck':
            print(song, '- AC/DC')
        elif song == 'Rebel Rebel':
            print(song, '- David Bowie')

嵌套循环

  1. 格式:

    for item1 in iterable1:
        for item2 in iterable2:
            do something
  2. 例子:

    for i in range(1, 10):
        for j in range(1, 10):
            print('{} X {} = {}'.format(i, j, i * j))

while循环

  1. 格式:

    while condition:
        do something
  2. 举例:

    count = 0
    while True:
        print('Repeat this line !')
        count = count + 1
        if count == 5:
            break
  3. 上面的登陆函数增加新功能:输入密码错误超过3次就禁止再次输入密码

    password_list = ['*#*#', '12345']
    
    def account_login():
        tries = 3;
        while tries > 0:
            password = input('Passowrd:')
            password_correct = password == password_list[-1]
            password_reset = password == password_list[0]
    
            if password_correct:
                print('Login success!')
            elif password_reset:
                new_password = input('Enter a new password:')
                password_list.append(new_password)
                print('Your password has changed successfully!')
                account_login()
            else:
                print('Wrong password or invalid input!')
                tries = tries - 1
                print(tries, 'times left')
        else:
            print('Your account has been suspended')
    
    account_login()

练习题

  1. 设计一个函数,在桌面上创建10个文本,以数字给它们命名。

    def create_files():
        desktop_path = 'C://Users/a/Desktop/'
        for i in range(1, 11):
            full_path = desktop_path + str(i) + '.txt'
            file = open(full_path, 'w')
            file.close()
  2. 设计一个复利计算函数invest(),它包含三个参数amount、rate、time。输入每个参数后调用函数,应该返回每一年的资金总额。

    def invest(amount, rate, time):
        for i in range(1, time + 1):
            amount = amount * (1 + rate)
            print('year {}: ${}'.format(i, amount))
  3. 打印1~100内的偶数

    for i in range(1, 101):
        if i & 1 == 0:
            print(i)

综合练习

  1. 设计一个猜大小的小游戏

    import random
    
    def roll_dice(numbers = 3, points = None):
        print("<<<<< ROLE THE DICE! >>>>>")
        if points is None:
            points = []
        while numbers > 0:
            point = random.randrange(1, 7)
            points.append(point)
            numbers = numbers - 1
        return points
    
    def roll_result(total):
        isBig = 11 <= total <= 18
        isSmall = 3 <= total <= 10
        if(isBig):
            return 'Big'
        elif(isSmall):
            return 'Small'
    
    def start_game():
        print("<<<<< GAME STARTS! >>>>>")
        choice = ['Big', 'Small']
        your_choice = input('Big or Small: ')
        if your_choice in choice:
            points = roll_dice()
            total = sum(points)
            youWin = your_choice == roll_result(total)
            if youWin:
                print('The points are', points, 'You win !')
            else:
                print('The points are', points, 'You lose !')
        else:
            print('Invalid Words')
            start_game()
    
    start_game()
  2. 在猜大小基础上增加如下功能:

    (1). 初始金额为1000元;

    (2). 金额为0时游戏结束;

    (3). 默认赔率为1倍,押对了能得到相应金额,押错了会输掉相应金额。

    import random
    
    def roll_dice(numbers = 3, points = None):
        print("<<<<< ROLE THE DICE! >>>>>")
        if points is None:
            points = []
        while numbers > 0:
            point = random.randrange(1, 7)
            points.append(point)
            numbers = numbers - 1
        return points
    
    def roll_result(total):
        isBig = 11 <= total <= 18
        isSmall = 3 <= total <= 10
        if(isBig):
            return 'Big'
        elif(isSmall):
            return 'Small'
    
    def start_game():
    
        money = 1000
        while money > 0:
    
            print("<<<<< GAME STARTS! >>>>>")
            choice = ['Big', 'Small']
            your_choice = input('Big or Small: ')
            rate = int(input('How much you wanna bet ? -'))
    
            if rate > money or rate < 0:
                print('Invalid Money')
            else:
                if your_choice in choice:
                    points = roll_dice()
                    total = sum(points)
                    youWin = your_choice == roll_result(total)
                    if youWin:
                        print('The points are', points, 'You win !')
                        money += rate
                        print('You gained {}, You have {} now'.format(rate, money))
                    else:
                        print('The points are', points, 'You lose !')
                        money -= rate
                        print('You lost {}, you have {} now'.format(rate, money))
                else:
                    print('Invalid Words')
        else:
            print('GAME OVER')
    
    start_game()
  3. 设计一个检验号码真实性的函数,检验规则如下:

    (1). 号码长度为11位;

    (2). 是移动、联通、电信号段中的一个电话号码(移动、联通、电信号段如下);

    CN_mobile = [134,135,136,137,138,139,150,151,152,157,158,159,182,183,184,187,188,188,147,178,1705]
    CN_union = [130,131,132,155,156,185,186,145,176,1709]
    CN_telecom = [133,153,180,181,189,177,1700]

    (3). 输入的号码外的其他字符可以忽略。

    def Phone_check():
    
        while True:
    
            CN_mobile = [134,135,136,137,138,139,150,151,152,157,158,159,182,183,184,187,188,147,178,1705]
            CN_union = [130,131,132,155,156,185,186,145,176,1709]
            CN_telecom = [133,153,180,181,189,177,1700]
    
            number_str = input('Input your number:')
            number = 0
            for i in range(len(number_str)):
                if number_str[i] >= '0' and number_str[i] <= '9':
                    number = number * 10 + int(number_str[i])
    
            first_three = int(str(number)[0:3])
            first_four = int(str(number)[0:4])
            if len(str(number)) == 11:
                if first_three in CN_mobile or first_four in CN_mobile:
                    print('Operater : China Mobile')
                    print('We\'re sending verification code via text to your phone:', number)
                    break
                if first_three in CN_union or first_four in CN_union:
                    print('Operater : China Union')
                    print('We\'re sending verification code via text to your phone:', number)
                    break
                if first_three in CN_telecom or first_four in CN_telecom:
                    print('Operater : China Telecom')
                    print('We\'re sending verification code via text to your phone:', number)
                    break
                else:
                    print('No such a operater')
            else:
                print('Invalid length, your number should be in 11 digits')
    
    Phone_check()

数据结构

列表

  1. 特征:

    (1). 表中的每个元素都是可变的;

    (2). 表中的元素都是有序的,都有自己的位置;

    (3). 列表可以容纳Python中的任何对象。

  2. 定义

    fruit = ['poneapple', 'pear']
  3. 添加元素

    插入的位置是实际指定位置之前的位置,如指定插入的位置在列表中不存在(实际上超出了指定列表长度)则元素会被放到列表的最后位置。

    fruit.insert(1, 'grape')
    fruit[0:0] = ['orange']
  4. 删除元素

    可以直接remove

    fruit.remove('pear')

    可以直接替换

    fruit[0] = 'apple'

    使用del关键字来声明

    del fruit[0:2]
  5. 查找元素

    输入对应位置就返回对应位置上的值

    periodic_table = ['H','He','Li','Be','B','C','N','O','F','Ne']
    
    print(periodic_table[0])
    print(periodic_table[-2])
    print(periodic_table[0:3])
    print(periodic_table[-10:-7])
    print(periodic_table[-10:])
    print(periodic_table[:9])

字典

  1. 特征

    (1). 字典中数据必须是以键值对的形式出现的;

    (2). 逻辑上讲,键(key)是不能重复的,值(value)可以重复;

    (3). 字典中,键是不可变的,而值是可以变的,可以是任何对象。

  2. 定义

    Dic = {key:value}
    Dic = {
        'A':'a',
        'B':'b',
        'C':'c'
    }
  3. 添加元素

    添加单一元素

    Dic[key] = value
    Dic['D'] = 'd'

    添加多个元素

    Dic.update({key1:value1, key2:value2})
    Dic.update({'E':'e', 'F':'f'})
  4. 删除

    使用del方法

    del Dic[key]
    del Dic['A']
  5. 索引

    输入对应key就返回对应value

元组

可以理解为一个稳固版的列表,因为元组不可修改。但元组可以被查看索引。

letters = ('a','b','c','d','e','f','g')
print(letters[0])

集合

  1. 特性:集合中的元素是无序的、不重复的任意对象,可以通过集合去判断数据从属关系、把数据结构中重复的元素减掉。

  2. 集合不能被切片也不能被索引,除了做集合运算外,集合元素还可以被添加和删除。

    (1). 集合运算

    a = set('abracadabra')
    b = set('alacazam')
    print(a)
    print(b)
    print(a - b)    # a中包含但b中不包含的元素
    print(a | b)    # 集合a或b中包含的元素
    print(a & b)    # 集合a和b中都包含的元素
    print(a ^ b)    # 不同时包含于a和b的元素

    (2). 添加和删除

    a_set = {2,1,1,3,4}
    print(a_set)
    a_set.add(5)
    print(a_set)
    a_set.discard(5)
    print(a_set)

数据结构的一些技巧

  1. 结合函数使用

    num_list = [6, 2, 7, 4, 1, 3, 5]
    print(sorted(num_list))
    print(sorted(num_list, reverse = True))
  2. 推导式(列表的解析式)

    (1). 格式

    list = [item for item in iterable]
    Dic = {key:value for item in iterable}
    a = [i**2 for i in range(1, 10)]
    b = [j + 1 for j in range(1, 10)]
    c = [k for k in range(1, 10) if k % 2 == 0]
    d = [l.lower() for l in 'ABCDEFGHIJKLMN']
    e = {i:i+1 for i in range(4)}
    f = {i:j for i, j in zip(range(1,6), 'abcde')}
    g = {i:j.upper() for i, j in zip(range(1,6), 'abcde')}

    (2). 将10个元素装进列表中的普通写法VS列表解析式的方法

    a = []
    for i in range(1, 11):
        a.append(i)
    print(a)
    b = [i for i in range(1, 11)]
    print(b)

    (3). 循环列表时获取元素的索引 普通写法 VS 用enumerate函数

    letters = ['a','b','c','d','e','f','g']
    
    i = 0
    for elem in letters:
        print(i, letters[i])
        i += 1
    for i, elem in enumerate(letters):
        print(i, elem)

综合项目

做一个词频统计项目

  1. 分割单词的方法:

    lyrics = 'The night begin to shine, the night begin to shine'
    words = lyrics.split()
    print(words)
  2. 词频统计初步实现(有bug):

    path = 'D://PythonCode/Walden2.txt'
    with open(path, 'r') as text:
        words = text.read().split()
        print(words)
        for word in words:
            print('{}-{} times'.format(word, words.count(word)))
  3. 上面代码的问题:

    (1). 带标点的单词被单独统计了;

    (2). 有些单词次数出现了多次;

    (3). 开头大写的被单独统计了。

  4. 解决方法:

    (1). 用strip函数移去单词里的标点符号;

    (2). 用lower将字符统一转换为小写;

    (3). 用set去重,用字典将每个单词出现的次数与单词对应起来。

    (4). 最后加序是为了让单词按照出现频率从大到小的顺序依次输出。

  5. 最终代码:

    import string
    
    path = 'D://PythonCode/Walden2.txt'
    with open(path, 'r') as text:
        words = [raw_word.strip(string.punctuation).lower() for raw_word in text.read().split()]
        words_index = set(words)
        counts_dict = {index : words.count(index) for index in words_index}
    
    for word in sorted(counts_dict, key = lambda  x : counts_dict[x], reverse = True):
        print('{} -- {} times'.format(word, counts_dict[word]))

定义

类是有一系列有共同特征和行为事物的抽象概念的总和。

在类里赋值的变量就是类的变量,类的变量有一个专有的术语,我们称之为类的属性

class CocaCola:
    formula = ['affeine', 'suger', 'water', 'soda']

实例化

在左边创建一个变量,右边写上类的名称,这种像赋值的行为,我们称之为类的实例化;被实例化后的对象,我们称之为实例,或者说是类的实例。

cola_for_me = CocaCola()
cola_for_you = CocaCola()

类属性的引用

在类后面输入.,IDE就会自动联想出我们之前在定义类的时候写在里面的属性,而这就是类属性的引用

由于类的属性会被所有类的实例共享,所以在类的实例后面再加上.,索引用的属性值是完全一样的。

print(CocaCola.formula)
print(cola_for_me.formula)
print(cola_for_you.formula)

实例属性

创建类之后,通过object.new_attr的形式进行一个赋值,于是我们就得到了一个新的实例的变量,实例的变量就是实例变量,而实例变量有一个专有的术语,我们称之为实例属性

cola_for_China = CocaCola()
cola_for_China.local_logo = '可口可乐'

print(cola_for_China.local_logo)

实例方法

方法就是函数,方法是供实例使用的,因此我们还可以称之为实例方法

class CocaCola:
    formula = ['affeine', 'suger', 'water', 'soda']
    def drink(self):
        print('Energy!')

cola = CocaCola()
cola.drink()

更多参数

和函数一样,类的方法也能有属于自己的参数。

class CocaCola:
    formula = ['affeine', 'suger', 'water', 'soda']
    def drink(self, how_much):

        if how_much == 'a sip':
            print('Cool~')
        elif how_much == 'whole bottle':
            print('Headache!')

ice_cola = CocaCola()
ice_cola.drink('a sip')

“魔术方法”

__init__():如果在类中定义了它,在创建实例时它就自动帮你处理很多事情——如增加实例属性

class CocaCola:
    formula = ['affeine', 'suger', 'water', 'soda']
    def __init__(self):
        self.local_logo = '可口可乐'

    def drink(self):
        print('Energy!')


cola = CocaCola()
print(cola.local_logo)
class CocaCola:
    formula = ['affeine', 'suger', 'water', 'soda']
    def __init__(self):
        for element in self.formula:
            print('Cola has {}!'.format(element))

    def drink(self):
        print('Energy!')

cola = CocaCola()

除了必写的self参数之外,__init__()同样可以有自己的参数,同时不需要obj.__init__()的方式来调用(因为是自动执行),而是在实例化的时候往类后面的括号中放进参数,相应的所有参数都会传递到这个特殊的__init__()方法中,和函数的参数的用法完全相同。

self.local_logo = logo_name中,左边是变量作为类的属性,右边是传入的参数作为变量。

class CocaCola:
    formula = ['affeine', 'suger', 'water', 'soda']
    def __init__(self, logo_name):
        self.local_logo = logo_name

    def drink(self):
        print('Energy!')

cola = CocaCola('可口可乐')
print(cola.local_logo)

类的继承

  1. 父类

    class CocaCola:
        calories = 140
        sodium = 45
        total_carb = 39
        caffeine = 34
        ingredients = [
            'High Fructose Corn Syrup',
            'Carbonated Water',
            'Phosphoric Acid',
            'Natural Flavors',
            'Caramel Color',
            'Caffeine'
        ]
    
        def __init__(self, logo_name):
            self.local_logo = logo_name
    
        def drink(self):
            print('You got {} cal energy!'.format(self.calories))
  2. 子类:父类中的变量和方法可以完全被子类继承,但如需有特殊的改动也可以进行覆盖。

    class CaffeineFree(CocaCola):
        caffeine = 0
        ingredients = [
    
            'High Fructose Corn Syrup',
            'Carbonated Water',
            'Phosphoric Acid',
            'Natural Flavors',
            'Caramel Color'
        ]
    
    
    cola_a = CaffeineFree('CocaCola-FREE')
    cola_a.drink()

类属性与实例属性


  1. Q1:类属性如果被重新赋值,是否会影响到类属性的引用?

  2. Q2:实例属性如果被重新赋值,是否会影响到类属性?

  3. Q3:类属性实例属性具有相同的名称,那么.后面引用的将会是什么?


  1. A1:会。

    class TestA:
        attr = 1
    
    obj_a = TestA()
    TestA.attr = 42
    print(obj_a.attr)    #42
  2. A2:不会。

    class TestA:
        attr = 1
    
    obj_a = TestA()
    obj_b = TestA()
    obj_a.attr = 42
    print(obj_b.attr)    # 1
  3. A3:实例属性。

    class TestA:
        attr = 1
        def __init__(self):
            self.attr = 42
    
    obj_a = TestA()
    print(obj_a.attr)    # 42

解释:__dict__是一个类的特殊属性,它是一个字典,用于存储类或者实例的属性,即使你不去定义它,它也会存在于每一个类中,是默认隐藏的。

让我们在上面代码中添加新的一行,结合代码理解一下:

class TestA:
    attr = 1
    def __init__(self):
        self.attr = 42

obj_a = TestA()
print(TestA.attr)   # 1
print(obj_a.attr)   # 42

Python中属性的引用机制是自内而外的,放你创建了一个实例之后,准备开始引用属性,这时候编译器会首先搜索该实例是否拥有该属性,如果有,则引用;如果没有,将搜索这个实例所属的类是否有这个属性,如果有,则引用,没有就报错。

Python中属性的引用机制

猜你喜欢

转载自www.cnblogs.com/songjy11611/p/12164398.html