Python学习笔记

程序设计思想与方法CS-902

  • 陆朝俊
  • 周二下午6-8节,12:55开始上课
  • 3学分,平时20%大作业30%期末(开卷)50%
  • 目标:学习了解计算思维,通过Python语言实现
课程安排 周次
教学课 1,2,3,4,5,7,9,11,13,14,15
上机课 6,8,10,12

课程笔记

  • 第一周

    1. 计算机的硬件组成,基本工作原理

    2. 程序设计语言:机器语言(二进制编码)、汇编语言(助忆符,需汇编器处理)、高级语言(适合人用,需编译器或解释器处理)

    3. 计算机解决问题步骤:先找出解决问题的方法步骤即算法,再用程序语言表达算法。关键:算法

    4. 算法的每一步必须是确切的,可行的,能在有限步内完成。

    5. 课程群名称来源CT-computational thinking(如何像计算机科学家那样思考)

    6. 计算思维:建立在计算机的能力(能做什么)和局限之上(不能做什么)

    7. 案例

      • 算法:小学算术的长除法
      • 查找:查黄页是顺序查找还是借助索引
      • 排序:整理扑克牌
      • 排队:先来先处理
      • 预取与缓存:书包存放当天上课要用的书(书包相当于缓存,寝室相当于硬盘)
      • 并行处理:同时烧几个菜
    8. 计算+X,拥有广泛的应用场景

    9. 课程定位 :学习利用计算机解决问题的实现方法,不是程序设计语言课程,不是算法和数据结构课程Python语言介绍:荷兰人Guido Van Rossum发明,简单开源高度可读性。编译+解释。

      Python版本越高反而丧失了高度可读性的初心。

      IDE:Intergrated Development Environment 集成开发环境

      Python程序防止一闪而过:最后添加输入语句

      • 程序构件:数据

        数据有不同类型,常见的有字符串,数字等

      • 程序构件:变量

        以字母或下划线开头,后跟字母等数字,区分大小写且有保留字(连字符、空格非法)

        良好的命名风格:有意义+保持一致风格(骆驼式,匈牙利命名标记,数据类型,例iMyage)

      • 程序构件:表达式

        良好编程风格:用空格,括号增加表达式的可读性,不依赖于优先级

      • 程序构件:语句

        输出语句,赋值语句(本课程主要用模板讲解语句,专业教材用巴克莱范式表示)

      • 程序构件:函数

        可以理解为把一段语句序列打包命名。用def来定义函数

      • 程序构件:注释

        # Author:Verification-Code

        # Version: 1.0.0

        def main():

      全书概要:信息抽象与数据表示

      两种符号化表示:字面值和标识符(PI等),Python通过赋值语句来定义变量,任何变量都必须先定义后使用。

      • 为了更精确的表示信息,编程语言提供不同数据类型。合法值+合法运算

        180+78一定有意义吗?




Python学习语法:

  1. 输出语句:Print(‘XXX’)

  2. 变 量:

    messgae="Hello World!"

    print(message)

    字符串:

    在Python中,用引号括起的都是字符串,其中引号既可以是单引号又可以是双引号,*这种灵活性主要是为了能让你在字符串中包含引号和撇号。

    1. 使用函数对字符串进行操作:例如

      name='ada lovelace'

      print(name.title()) 结果:Ada lovelace

      print(name.upper()) 结果:ADA LOVELACE

      print(name.lower()) 结果:ada lovelace(较常用,统统先转成小写在存储)

    2. 在字符串中使用变量

      first_name="ada"

      last_name="lovelace"

      full_name=f"{first_name}{last_name}''

      print(full_name)

      要在字符串中插入变量的值,可在前引号前加入字母f,再将要插入的变量放在花括号内,这样,当Python显示字符串时,将每个变量都替换为其值。,这种字符串名为f字符串,f是format缩写。由此可以完成很多工作。(注意,f字符串是Python3.6引入的,对于之前的版本,full_name="{}{}".format(first_name,last_name)

    3. 使用制表符或换行符来添加空白

      在编程中,空白泛指使用任何非打印字符,如空格,制表符或换行符。

      空白:\t(制表符)

      换行:\n(换行符)

      反斜杠:\

      单引号:\ ’

      双引号:\ "

    4. 取子串

      若s=“Hello Bob”

      s[0:3]是‘Hel’

      s[:]是‘Hello Bob’

    5. 也可以用+号直接连接

    6. 一个字符串的重复连接,用乘*

    7. 字串检测,用in

    8. 注意,字符串不可修改

    9. ord函数可以返回字符的编码

      ord(‘a’)=97

      ord(‘\xc4’)=196,这里\x表示16进制。

      print(‘\xc4) 结果为A上带两点

    10. eval()函数将字符串当作数值表达式计算

    11. str()函数自动将计算结果转成字符串

    12. String库内也有很多字符串函数

    删除空白

    自动剔除字符串末尾空白:favorite_language.ratrip()

    自动剔除字符串开头空白:favorite_language.lstrip()

    自动剔除字符串首尾空白:frvorite_language.strip()

    在Python中,可用**表示乘方运算,将任意两个数相除时,结果总是浮点数,即使这两个都是整数且能整除。

    书写很大的数时,可使用下划线将其中的数字分组,使其更清晰已读,当你打印这种数时,Python 不会打印其中的下划线。(Python>=3.6)

    同时给多个变量赋值:x,y,z=0,0,0

    常量:Python没有内置的常量类型,但Python程序员会使用全大写来指出应将某个变量视为常量,其值应该始终保持不变

    MAX_CONNECTIONS=5000

    注释

    Python语言中使用井号做注释标识,井号后面的内容会被Python解释器自动忽略,#向大家问好

    彩蛋

    Python之禅:import this



第三章:列表

列表由一系列特定顺序排列的元素组成,如下

bicycles=['track','cannodale','redline','specialized']

print(bicycles)

结果如下

['track','cannodale','redline','specialized']

Python将打印列表的内部表示,包括方括号。

访问列表元素,只需告诉该元素的位置(索引),当然需要特别注意的是索引从0开始而非1开始,且Python为访问最后一个元素提供了一种方法,就是直接用-1去索引。

print(bicycles[1])

当然,也可以同时调用那几个对字符串处理的函数title()等。

你可以像使用其他变量的值一样使用列表中的各个值,例如使用f组成一个新的字符串。

如何修改列表元素呢?

修改:对特定索引元素直接进行重新赋值即可

添加:1. 列尾(对空列同样适用)例如:

motorcyles=[]

motorcyles.append('homda')

motorcyles.append('ymaha')

motorcyles.append('suzuki')

​ 结果不言自明(注意方括号也是会输出的)

​ 插入,使用函数insert(),如下

motorcyles.insert(0,'ducati')

删除:知道元素索引,可以使用del语句,例如 del motorcyles[0]

​ 知道元素索引且需要将这个元素单独拿出来,用pop()即出栈的方法,如果不指定索引则默认弹出列尾元素。

popped_motorcyles=motorcyles.pop()

first_owned=motorcyles.pop(0)

​ 根据值去删除元素,用remove函数

motorcyles.remove('ducati'),注意函数remove()只删除第一个指定的值,如果要删除的值在表中可能出现多次,则可以 使用循环。

如何对列表进行排序

  1. 按照字母排列

    cars=['bmw','audi','toyota','subaru']

    cars.sort()

    按照字母反序排列

    cars.sort(reserve=True)

    注意这是对列表元素顺序的永久修改

  2. 使用函数sorted对列表临时排序

    要保留列表元素原来的排列顺序,同时以特定的顺序呈现他们,可使用函数sorted()

  3. 使用函数reserve来使列表倒序

    cars.reserve()

    注意这样是永久修改的,当然你可以随时再次用这个函数使其倒回去

  4. 使用函数len来确定列表的长度

    cars.len()



第四章:操作列表

  1. 遍历整个列表

    magicians=['alice','david','carolina']

    for magician in magicians:

    print(magician)

  2. 特别注意,在for循环中,只有for循环下缩进的语句才会循环执行

  3. 避免缩进错误!(4个空格缩进)

    • 忘记缩进

    • 忘记缩进额外的代码行

    • 不必要的缩进

    • 循环后不必要的缩进

    • for循环语句遗漏了:

  4. 创建数值列表(数组)

    • 使用函数range()

      for vaule in range(1,5)

      print(vaule)

      结果

      1

      2

      3

      4

      为什么没有打印5呢?这是编程语言中常见的差一行为,函数range到达指定的第二个值时停止,因此不执行print(5)

      调用函数range()时,也可只指定一个参数,这样他将从0开始。

    • 使用range创建数值列表

      numbers=list(range(1,6))

      print(numbers)

      结果如下

      [1,2,3,4,5]

    • range指定步长

      even_numbers=list(range(2,11,2))

      print(even_numbers)

      结果

      [2,4,6,8,10]

    • 对数值列表的初步统计

      digits=[1,2,3,4,5,6,7,8,9,0]

      min(digits)

      max(digits)

      sum(digits)

    • 列表解析

      squares=[value**2 for value in range(1,11)]

      print(square)

      结果

      [1,4,16,25,36,49,64,81,100]

    • 列表切片

      players=['charles','martina',michael','florence','eli']

      print(players[0:3])

      其实可以指定三个参数,第一个起始位(可略,头),第二个终止位(可略,尾),第三个是步长

    • 遍历切片

      使用for循环实现

    • 复制列表

      方法:同时省略起始索引和终止索引

      特别注意如果这样

      friend_foods=my_foods

      这是错的,这里将后面直接赋给前面,而不是将后面的副本赋给前面,因此这两个变量指向同一个列表。

    1. 元组

      列表是可以变动的,而元组是不可以变动的列表,元组看起来很像列表,但是使用圆括号而非中括号来标识。

      dimensions=(200,50)

      遍历元组中的所有值

      dimensions=(200,5)

      for dimension in dimensions:

      print(dimension)

      虽然不能修改元组的元素,但可以给存储元素的变量赋值,即重新赋值覆盖一遍



第五章:if语句

  示例:
   
     `cars = ['audi','bmw','subaru','toyota']
   
     for car in cars:
   
     if car == 'bmw'
   
     	print(car.upper())
   
     else:
   
     	print(car.title())`













  1. 条件测试

car = 'audi'

car == 'bmw'

结果

False

当然,这是需要区分大小写的,不等为!=,>,<,>=,<=

也可以使用and和or检查多个条件

检查特定值是否表示在列表中,in

'mushrooms' in requested_toppings

当然,可以用 not in判断不在

布尔表达式

  1. IF 语句

    if-elif-else语句

    注意可以使用多个elif语句,也可以省略else语句

  2. 用if语句处理列表

    requested_toppings=[]

    if requested_toppings:

    这里if会做检查,如果是空的,返回False,非空返回True

    基本就是语言的基本if操作



第六章:字典

一个简单的字典如下

alien_0={'color':'green', 'point':5}

print(alien_0['color'])

print(alien_0['points'])

大概就是查字典吧

在Python中,字典用放在花括号{}中的一系列键值对表示。

访问字典中的值,可依次指定字典名和放在方括号内的键

  • 添加键值对

    alien_0['x_position']=0

    alien_0['y_position']=0

    用花括号创建新字典

    alien_0={}

  • 修改字典中的值

    alien_0['color']='yellow'

  • 删除键值对

    del alien_0['points']

  • 由类似对象组成的字典

    favorite_languages={

    'jen': 'python',

    'sarah': 'c',

    'edward': 'ruby',

    'phil': 'python',

    }

  • 使用get()来访问值

    如果直接用键取访问字典而对应的键值不一样时,系统会报错。

    为了避免这样,可以使用方法get()在指定键不存在时返回一个默认值。

    方法get()的第一个参数用于指定键,是必不可少的;第二个参数为指定的键不存在时要返回的值,是可选的。

    point_value=alien_0.get('points','No point vaule assign.')

  • 遍历字典

    1. 用for循环去遍历

      for key,value in user 0.item():

      print(f"\nKey: {key}")

      print(f"Value: {value}")

      注意这里的循环变量名字是任意指定的,只需要保证有两个循环变量即可,如可以是name和age

    2. 遍历字典中的所有键

      在不需要使用字典的值时,方法Keys()很有用。

      for name in favorite_languages.keys():

      print(name.title())

      遍历字典时,如果使用for name in favorite_languages:

      输出将不变,即单变量循环默认为值,当然,显式地使用方法keys()可让代码更容易理解

      方法Keys()并非只能用于遍历,实际上,它返回一个列表,其中包含字典中的所有键。

    3. 按照特定循序遍历字典中的所有键

      从Python3.7起,遍历字典时将按插入的循序返回其中的元素。

      要以特定循序返回元素,一种办法是在for循环中对返回的键进行排序,为此,可使用函数sorted()来获取对特定顺序排列的键列表副本:

      for name in sorted(favorite_languages.keys()):

      print(f"{name.title()}, thank you for taking the poll.")

      这里就是对keys()返回的列表,并用sorted()方法进行按照首字母排序

    4. 遍历字典中的所有值,可以使用方法values()

      最粗暴的做法是这样的

      for language in favorite_languages.values():

      print(language.title())

      这条for语句提取字典中的所有值,并将其一次赋值给变量language,这种做法提取字典中的所有值,而没有考虑是否重复,为了剔除重复项,可以使用集合(set),集合中的每个元素都是独一无二的。

      for language in set(favorite_languages.values()):

      通过更深入的学习Python,你会发现它内置的功能可以帮助你以希望的方式处理数据。

    5. 可以用一对花括号直接创建集合,并在其中用逗号分隔元素:

      >>>language = {'python', 'ruby', 'python', 'c'}

      >>>languages

      {'ruby','python','c'} #输出结果

      集合和字典很容易混淆,因为他们都是用一对花括号定义的,当花括号中没有键值对时,定义的很可能是集合,不同于列表和字典,集合不会以特定顺序存储元素。

    6. 嵌套

      将一系列字典存储在列表中,或将列表作为值存储在字典中,这称为嵌套

      字典alien_0包含了一个外星人的各种信息,但无法存储第二个外星人的各种信息,更别说屏幕上所有外星人的基本信息了,一种办法是创建一个外星人列表,其中每个外星人都有一个字典,包含有关该外星人的所有信息,如下

      aliens = [alien_0,alien_1,alien_2]

      for alien in aliens:

      print(alien) #结果将会将三个外星人的字典完整打印出来

      进一步地,可以使用for循环等自动生成这些东西

      # 创建一个用于存储外星人的空列表

      aliens = []

      # 创建30个绿色的外星人、

      for alien_number in range(30)

      new_alien = {'color': 'green', 'points': '5', 'speed': 'slow'}

      aliens.append(new-alien)

      # 显示前5个外星人

      for alien in aliens[:5]:

      print(alien)

      print("...")

      # 显示创建了多少外星人。

      point(f"Total number of aliens: {len(aliens)}")

      经常需要在列表中包含大量的字典,而其中每个字典都包含特定对象的众多信息。例如,你可能需要为网站的每个用户创建一个字典,并将这些字典存储在一个名为users的列表中,在这个列表中,所有字典的结构都相同,因此你可以遍历这个列表,并以相同的方式处理每个字典。

    7. 在字典中存储列表

      pizza = {

      'crust': 'thick',

      toppings': ['mushrooms', 'extra cheese'],

      }

      每当字典中将一个键关联到多个值时,都可以在字典中嵌套一个列表,在本章前面有关喜欢的编程语言的示例中,如果将每个人的回答都存储在一个列表中,被调查者就可以选择多种自己喜欢的语言,在这种情况下,当我们遍历字典时,与每个被调查者相关联的都是一个语言列表。因此,在遍历该字典for循环中,我们需要再使用一个for循环来遍历与被调查者相关联的语言列表。

    8. 在字典中存储字典

      例如,如果有多个网站用户,每个都有独特的用户名,可在字典中将用户名作为键,然后将每位用户的信息存储在一个字典中。

      users = {

      'asinstein': {

      'first': 'albert',

      'last': 'einstein',

      'location': 'princeton',

      },

      'mcurie': {

      'first': 'marie',

      'last': 'curie',

      'location': 'paris',

      },

      }

      请注意,表示每位用户的字典都具有相同结构,虽然Python语言没有这样的要求,但这使得更嵌套的字典处理起来更容易。



第七章:用户输入和while循环

  1. 函数input()的工作原理

    函数input()让程序暂停运行,等待用户输入一些文本,获取用户输入后,Python将其赋给一个变量,例如

    message = input("Tell me something, and i will repeat in back to you: ")

    每当使用函数input()时,都应指定清晰易懂的提示,准确地指出希望用户提供什么样的信息。

    有时候提示可能会超过一行,此处我们给出创建多行字符串的方法

    prompt = 'If you tell us who you are, we can personalize the messages you see.'

    prompt += "\nWhat is your first name"

    2. 使用int()来获取数值输入
    

    使用input()时,Python将用户输入解读为字符串,例如

    >>>age = intput("How old are you?")

    How old are you? 21

    >>> age

    ‘21’

    如果试图将输入作为数来使用,就会引发错误

    为了解决这个问题,可以用int(),函数int()将输入字符串转变为数值表示,如下

    实际上是强制类型转换

    3. 求模运算符%
    

    将两个数相除并返回余数

    4. 整除运算符//
    

    将两个数执行除法,对结果舍去小数部分,注意结果可能不为整数,可能与分子相关

    5. While循环简介
    

    样例

    current_number = 1

    while current_number <= 5

    print(current_number)

    current_number +=1

    人工指定是否退出循环

    while message != 'quit':

    message = input(prompt)

    print(message)

    使用标志Flag

    active = True

    while active:

    message = input(prompt)

    ​ if message == ‘quit’:

    ​ active = False

    ​ else:

    ​ print(message)

    使用break强制退出循环

    在循环中使用continue跳过当前循环

    避免无限循环,如果实在发生的无限循环,可以使用Ctrl+C强制停止

    6. 使用While循环处理列表和字典
    

    for循环是一种遍历列表的有限方式,但不应该在for循环中修改循环列表,否则将导致Python难以跟踪其中的元素,要在遍历列表的同时对其进行修改,可使用While循环。

    • 样例,在列表中移动元素

      *假设有一个列表包含新注册但还未验证的网站用户,验证这些用户后,如何将他们移到另一个已验证的用户列表中?一种方法是使用Whi了循环,在验证用户的同时将其从为验证用户列表中提取出来,再将其加入另外一个已验证用户列表中。例如

      # 首先,创建一个待验证用户列表

      # 和一个用户存储已验证用户的空列表

      unconfirmed_users = ['alice', 'brain', 'candace']

      confirmed_users = []

      # 验证每个用户直至没有未验证用户为止

      # 将每个经过验证用户都移动到已验证用户列表

      while unconfirmed_users:

      current_user = unconfirmed_user.pop()

      print(f"Verifying user: {current_user.title()}"

      confirmed_users.append(current_user)

      # 显示所有已验证用户

      print("\nThe following users have been confirmed:")

      for confirmed_user in confirmed_users:

      print(confirmed_user.title())

    • 删除为特定值的所有列表元素

      while循环+remove语句

    • 使用用户输入来填充字典

      # 提示输入被调查者的名字和回答

      name = input("\nWhat is your name?")

      response = input("Which mountain would you like to climb someday?")

      # 将回答存储在字典中

      responses[name] = response



第八章:函数

函数是带名字的代码块,用于完成具体的工作,要执行函数定义的特殊任务,可调用该函数,需要在程序中多次执行同一项任务。

  1. 定义函数

    def greet_user()

    print("Hello!")

    great_user()

  2. 向函数传递信息(传参)

    def greet_user(username)

  3. 实参和形参

    调用函数时,将实参传给了函数,这个在调用时被赋值给了形参

  4. 传递实参

    函数定义中可能需要包含多个形参,因此函数调用中也可能包含多个实参,向函数传递实参的方式很多,可以用位置实参,这要求实参和形参的顺序相同;也可以使用关键字实参,其中每个实参都由变量名和值组成;还可以使用列表和字典,具体如下

    • 位置实参

      def describe_pet(animal_type, pet_name):

      # 调用如下

      describe_pet('hamster', 'harry')

    • 关键字实参

      关键字实参是传递给函数的名称值对,因为直接在实参中将名字和值关联起来,所以向函数传递实参时不会混淆,关键字实参让你无需考虑函数调用中的实参顺序(位置实参:勿cue),还清楚地指出了函数调用中各个值的用途

      describe_pet(animal_type='hamster', pet_name='harry')

    • 默认值

      编写函数时,可以给每个形参指定默认值,例如

      def describe_pet(pet_name, animal_type='dog'):

      如果显示给定了实参,Python将自动忽略形参默认值。

    • 等效的函数调用

      对前面那些语法进行综合使用,合法合理即可

    • 避免实参错误

    返回值

    • 返回返回值

    • 让实参变成可选的,方法是在函数接收入实参后做一个判断,如果是空的怎么怎么样,如果是非空的怎么怎么样

    • 返回字典

    • 结合使用函数和while循环

    • 传递列表

    • 在函数中修改列表

    • 禁止函数列表

      只让原来的列表传递副本,其实就是临时拷贝一份

      function_name(list_name[:])

    • 传递任意数量的实参

      def make_pizza(*toppings):

      形参名*toppings中的星号让Python创建一个名为toppings的空元组,并将收集到的所有信息封装在这个空元组中。

    • 结合使用位置实参和任意数量实参

      def make_pizza(size,*toppings)

    • 使用任意数量的关键字实参

      def build_profile(first,last,**user_info):

      形参名**user_info中的两个星号让Python创建一个名为user_info的字典

    • 将函数存储在模块中

      新建一个py文件,只写入函数的代码

      在其它文件夹中导入该模块即可 import pizza

      还有一种是导入特定的函数

      from module_name import fuction_name

      从什么模块导入什么函数

      使用as给函数拟定别名

      from module_name import pizza as good

      使用as给模块拟定别名

      import module_name as good

      导入模块中的所有函数:from pizza import *(不推荐)



第九章:类

  1. 创建类和使用类

    class Dog:

    ​ def _init_(self,name,age):

    当然,带默认值是可以的,直接更新属性的值(或者使用方法(函数)更新))

  2. 继承

    编写类时并非总是要从空白开始,如果要编写的类是另一个现成类的特殊版本,可以使用继承。父类和子类

    class ElectricCar(Car):

    与正常类的定义区别就是多了一个括号和父类名,使用继承时父类必须包含在文件中且在子类前面,然后记得加上super()./init /(make,modle,year)

    先初始化父类的属性,再初始化子类特有的属性

    可以在子类中重写父类的方法,也就是同函数名直接覆盖

    将实例作用于属性,实际上就是组合,在一个类中包含另外一个类

    模拟实物,从较高的实物层面去划分这个世界

  3. 导入类

    专门开一个文件用来存放py代码即可,也可以在一个文件中存储多个类,一次性从一个模块中导入多个类,还可以导入整个模块,导入模块的所有类,在一个模块中导入另外一个模块,使用别名,还有必要的Python标准库



第十章: 文件和异常

  1. 读取文件

    with open('pi_digits.txt') as file_object:

    contents = file_object.read()

    prints(contents)

    有open()函数也有close()函数

    注意,read()到达文件末尾时会多出来一个空行,可以使用rstrip()方法

    注意文件路径问题

    使用for循环逐行读取

    with open(filename) as file_object:

    注意,这里使用read()函数后每行结束后会多出来一个空格

    读取文本文件时,Python将其中所有的文本都解读为字符串.

    经典项目:圆周率包括你的生日吗?

    for line in lines:

    pi_string += line.strip()

    birthday = input("Enter your birthday,in the form mmddyy: ")

    if birthday in pi_string:

    print ......

    else:

    print......

  2. 写入文件

    要将文本写入文件,你在调用open()时需要提供另一个实参,告诉Python你要写入打开的文件

    with open(filename,'w') as file_object

    w写入模式,a是附加模式,r+是读写模式

    写入多行需要自己准备换行符

    使用附加模式添加到文件末尾

  3. 异常

    使用try-except方法,pass语句

  4. 存储数据

    json.load,json.jump

  5. 代码重构



第十一章:测试代码

  1. 测试函数

    单元测试和测试用例

    导入模块unittest和要测试的函数,再创建一个继承unittest.Testcase的类,并编写一系列方法对函数行为进行不同方面的测试

    各种断言方法及其使用