jk's notes

ch01 起步

1. 编程环境简介与安装

主要说明不同系统中 python 存在一定差异. 本章重点是安装.

本书基于 python3.11 的版本, 理论上 python3.9+ 的版本都可以运行书中的代码.

可以在终端尝试运行 python, 演示了本书如何展示代码, 其中 >>> 是命令提示符.

本书采用 VSCode 作为编辑器. 本书附录 B 介绍了一些其他的编辑器.

然后介绍在各个操作系统中安装 python (win, macOS, Linux).

  • win 安装注意, 在安装向导过程中, 添加到环境变量.

在终端打印 python 即可看到是否安装成功:

image-20231226181859310

安装 VSCode, 以及 python 扩展 (在扩展中搜索, 选择 Microsoft 的扩展).

image-20231226182218062

2. 运行 Hello World 程序

步骤:

  1. 在桌面创建文件夹 python_work. 用于放置项目 (建议字符使用小写字母, 下划线代替空格).

  2. 使用 VSCode 开发文件夹, 创建 hello_python.py 文件.

  3. 编写代码:

    print("Hello Python World!")
    
  4. 运行程序, 选择菜单栏 Run > Run Without Debugging 或 Ctrl + F5.

具体用法可以参考附录 B.

image-20231226182918436

image-20231226182942859

注意:

  • 如果没有安装 python 扩展, 直接 Ctrl+ F5 会提示安装扩展.
  • Ctrl + F5 是只运行, 不调试.
  • F5 是运行 + 调试.

然后作者介绍了上述程序如果运行失败可能存在的问题 (略).

3. 在终端运行 python

使用命令:

python <python 文件>.py

需要注意在 Linux 和 macOS 中 python 命令时指 python2, 应该使用 python3 命令.

即 python3 <python 文件>.py.

ch02 变量和简单的数据类型

1. 运行 hello_world.py 时发生的情况

运行 .py 文件时, 后缀名 .py 表示它是一个 python 程序, 因此会使用 python 解释器来读取整个文件, 然后解析它, 最后再执行.

在解析的过程汇总, 解释器会知道代码中有什么变量, 使用了什么函数. 使用编辑器的时候也会有语法高亮, 这个功能也是对代码进行词法解析得到的.

2. 变量

变量的语法: 直接使用标识符 = 值 即可.

message = 'Hello PythonWorld!'

message 为变量名, 不需要 var 等关键词引导声明

字符串使用单引号, 双引号均可

不需要分号结尾

变量的值可以随时修改, 再使用 (逻辑上, 无类型)

2.1 变量的命名与使用

组成:

  • 字母, 数字, 下划线组成. 不能以数字开头.
  • 不允许包含空格.
  • 勿使用关键词或函数名作为变量名.
  • 慎用 1, l, 0, O 等字符. 变量名应简明, 命名应见名得义.

py3 支持中文变量名, 但不推荐.

变量名大小写敏感, 但一般大写字母有特定用法, 变量名使用小写为宜.

2.2 避免命名错误

如果编写出现错误, 解释器会给出报错.

话说 IDE 也可以

image-20240109172709670

2.3 变量是标签

对变量的一个白话解释性描述.

3. 字符串

字符串 (string) 是一系列字符. 在 py 中使用单引号, 或双引号括起来的都是字符串.

这个可以在字符串中嵌入引号. 例如 "I'm a student" 等

3.1 大小写

针对英文内容字符串

.title() 方法. 将每个单词首字母大写, 其余字符小写. 返回新字符串, 不会对源字符串修改.

.upper() 方法. 全大写.

.lower() 方法. 全小写.

3.2 在字符串中使用变量

就是插值. 使用语法: f 来引导字符串. 使用花括号来插值. 例如:

message = f"abc{ variable }"

3.3 使用空白

用来对齐, 布局. 常用的如 空格, 制表符 (\t), 换行符 (\n) 等.

3.4 删除空白

返回新字符串, 并非对源字符串修改. 可将修改结果赋值回源字符串来实现修改.

  • .strip(). 去除两端空白.
  • .rstrip(). 去除右边空白.
  • .lstrip(). 去除左边空白.

3.5 删除前缀

  • .removeprefix(). 删除字符串前缀.

4. 数

数字类型支持使用 _ 作为分隔符使用. 例如: 1_000_000

4.1 整数

运算: +, -, * ,/ (小数除法), ** (乘幂).

优先级与数学中一致. 使用括号调整优先级.

4.2 浮点数

带有小数点的数字是浮点数

需要注意的是: 0.1 + 0.2 不等于 0.3

本书第二部分会介绍如何处理多余小数位

4.3 整数与浮点数

说的是隐式类型转换. 略.

4.4 数中的下划线

一个语法糖, 在数字表示时易于阅读, 但底层存储忽略下划线.

image-20240109181522169

组合数字的时候, 一般会从右向左三个一组 (整数部分).

4.5 同时为多个变量赋值

类似于 js 总解耦的语法:

x, y, z = 1, 2, 3

image-20240109181710079

4.6 常量

Python 没有常量的语法, 但一般采用全大写形式的名字来描述常量.

例如: MAC_CONNECTIONS = 5000.

5. 注释

单行注释: ##

6. Python 之禅 (约定与思想, 略)

代码要简洁.

ch03 列表简介

简单来说就是数组, 集合, 这类线性数据类型.

1. 列表是什么

列表 list 就是一列元素, py 并没有约定每一个元素的类型必须一致.

语法:

list = [ 元素, 元素, ... ]
  • 使用方括号界定列表
  • 使用逗号分隔元素

打印列表的时候, 会以内部格式打印, 包括方括号.

1.1 访问元素

使用 [index] 索引来访问元素.

注意索引从 0 开始.

如果使用负数作为索引, 是从后往前检索元素. -1 表示最后一个.

逻辑上 -n 就是 length - n.

2. 修改, 添加和删除元素

2.1 修改元素

使用下标访问, 直接赋值.

2.2 添加元素

追加使用 .append() 方法.

插入元素使用 .insert(index, elem) 方法.

2.3 删除元素

  • 使用 del 语法删除. 语法与 JS 一样. del list[index].

不同的是, 删除不同于 JS 会变成稀疏数组, 后续的元素索引会自动前移

  • pop() 方法也可以弹出一个元素 (注意从结尾处弹出).
  • pop() 可以带有索引参数, 表示删除对应位置的元素 (pop 可以看成是 removeAtIndex).
  • 还有一个 remove 方法, 根据等值判断删除第一个出现的元素, 如果元素不存在会报错.

3. 列表管理

简单来说就是操作数组, 涉及到排序

  • .sort() 方法, 永久排序. 默认按字母排序, 如果带有参数 reverse=True 则采用降序.
  • sorted() 函数会根据数组生成一个新的排序好的数组, 源数组不变. 也可以传入 reverse 参数.
  • 翻转数组 .reverse().
  • len() 获取数组长度.

4. 避免索引使用错误

  • 超出索引范围

ch04 操作列表

遍历列表:

for 迭代变量 in 列表:
  循环体

注意, python 使用索引来表达层级.

书中相关小结: 深入研究循环, 是对循环语法的解释; 在 for 中执行更多, 相当于解释使用代码块来表示循环体, 来执行多个语句; 而在 for 循环后执行, 是说在循环结束后需要移除缩进.

一个习惯是在循环结束后加一个空行.

注意 for 循环体中是允许有空行的.

避免缩进的错误

  • 多缩进, 少缩进.

  • 遗漏冒号.

3. 创建数值列表

之前都是字符串列表, 这里介绍数值列表.

  • range(left, right) 函数. 创建一个左闭右开的整数区间集合.
  • range() 允许第三个参数, 用于表示步长 (相当于默认为 1). 可用来构造等差数列.

借助于 range 可以创建出任意的数值列表. 例如构建等差数列:

_base = range(1, 10)
arr = []
for n in _base:
  arr.append(n * 2)

需要注意的是 range 生成的不是列表, 可以理解为是一个结构.

jk: 初步理解为一个延迟执行的结构, 表示的是一个列表的结构.

jk: 新版的内容与旧版的内容有些不同, 将 range 转换为列表, 可以使用 list() 函数

简单统计

  • max()
  • min()
  • sum()

列表推导式*

很好用. 很好用. 很好用.

[使用迭代变量的表达式 for 迭代变量 in 基列表]

如创建等差数列

[v * 2 for v in range(1, 11)]

再如计算函数 f() 的映射可以写成

[f(v) for v in range(1, 11)]

4. 使用列表的一部分

4.1 切片 (slice)

语法:

列表[startIndex:endIndex]
  • 切片返回的就是列表.

  • startIndex 可省略, 默认为 0, 注意冒号不能省略. 也支持负数索引.

  • endIndex 可省略. 默认为全部.

  • 使用 [:] 可以复制列表 (列表可以理解为引用类型, 不能直接使用变量赋值得到).

5. 元组 (tuple)

列表是可变的, 元组是不可变的.

t = (item1, item2, ...)

列表使用方括号, 元组使用圆括号.

访问元素单个索引位置的元素, 语法与 列表一样. 使用 [index]

注意, 元素是由 逗号分隔的, 括号只是为了好识别, 若单个元素的元组需要写成 (3,)

元组遍历与列表相同.

6. 设置代码格式 (规范, 略)

缩进 4 空格,

行长 80 字符.

注意使用空行, 有助于理解代码.

ch05 if 语句

语法:

if 表达式:
  语句
elif 表达式:
  语句
else:
  语句

逻辑运算符: and, or, 使用圆括号可以修改优先级.

关系运算符: >, >=, <, <=, ==, !=.

判断是否在列表中: v in list 与 v not in list.

对于 数值 0, 空值 None, 空字符串 '' 或 "", 空列表 [], 空元组 (), 空字典 {}, 都会被识别为 False.

然后用一个案例, 解释了两个列表交集运算的应用.

ch06 字典

逻辑上就是 JSON 格式的数据.

  • 创建字典, JSON 格式 (key 是字符串, 要用引号)
  • 访问字典成员, 使用 [key] 索引.
  • 添加项, 使用 dic[key] = value, 这个语法也适用于修改字典值. 也可以从空字典开始创建.
  • 删除字典值, 使用 del dic[key].

读取字典项时, 如果键不存在, 会报错. 可以使用 get() 方法来获取值:

字典.get('键名', '默认值') ## 在键不存在时, 返回默认值

遍历字典:

for key, value in 字典.items():
  循环体

使用字典的 keys() 方法可以遍历字典中的所有键. 还有 values() 方法.

默认函数 set() 可以利用源创建出不重复的集合来.

嵌套

列表项为字典的情况, 或其他. 就是构造复杂数据类型.

ch07 用户输入和 while 循环

1. input()

  • 该方法会阻塞终端, 等待用户输入
  • 该方法会在平面上输出提示文字
  • 该方法待用户输入数据后 (字符串类型), 会将输入作为返回值返回.
msg = input('提示文字')

使用 \n, \t 等格式化提示文字.

使用 int() 函数可以将字符串转换为数字.

求模运算符 %

2. while 循环

while 表达式:
  语句

然后讨论了怎么来控制表达式让用户输入某些数据后结束循环.

然后介绍了 break 关键字, 跳出循环.

介绍 continue 关键字, 进入下一轮循环.

注意: 避免死循环

3. 使用 while 处理列表和字典

for 循环基于索引, 不应该在 for 循环中对列表进行有关索引变更的操作.

可以考虑使用 while 循环.

介绍了两个案例:

  • 循环变量列表中的元素, 将列表中的元素一个个移动到另一个列表中.
  • 循环删除列表中的某一个值的元素 (默认 remove() 只会删除第一个).

while 循环条件如果是列表, 当列表中没有元素时也判定为 False

判断列表中是否含有某个元素, 可以使用 元素 in 列表 来判断.

使用字典. 字典的逻辑与 JSON 一样.

dic = {} ## 创建字典
dic[key] = value ## 存储键值对

使用 for in 循环遍历字典

for k, v in dic.items():
  ## 使用 k 表示键, 使用 v 表示对应的值

注意迭代变量的顺序

ch08 函数

定义函数语法:

def 函数名():
  函数体

调用语法:

函数名()

介绍了文档字符串, 使用三引号, 它是一个块级注释.

然后介绍了传参, 实参形参的概念.

  • 位置实参. 就是按照定义的参数顺序依次传入参数 (无新, 只是引入新概念).
  • 关键字实参. 即为命名参数, 利用 name=value 的形式传参, 可以不考虑顺序.

然后介绍了参数 默认值.

函数返回值也使用 return 值.

可先参数 (可以使用默认值来使得参数可选, 置空字符串, if 可判断)

空字符串作为 判断条件, 被认定为 False

然后介绍如何在函数中返回字典.

然后介绍将列表作为参数传入函数. 并介绍在函数内对列表元素进行修改 (引用传递的问题).

然后介绍阻止在函数内对列表进行修改 (使用 [:] 传入列表的副本, 修改也没用).

最后作者提到了, 少用函数副本, 会有性能问题.

然后介绍传入任意个数的位置实参. 在参数名前使用星号, 在函数中将其作为元组使用.

def 函数名(*参数名):
  函数体

逻辑上就是 c## 的 params, 或 js 中的 ...

然后介绍任意数量的关键字实参. 使用两个前置星号. 那么参数就成了字典类型.

def 函数名(**参数):
  函数体

将函数存储在模块中

导入模块的语法

导入使用 import 语法导入整个模块.

import 文件名

文件名作为模块名, 不需要后缀.

所谓模块就是包含代码的 py 文件. (似乎没有什么特殊的语法来限制访问).

导入后, 模块名作为命名空间使用.

导入特定函数

语法:

from 模块名 import 函数名

如果有多个函数, 用逗号分隔.

使用 as 为函数取别名

from 模块名 import 函数名 as 别名

使用 as 为模块取别名

import 模块名 as 别名

导入模块中的所有函数

from 模块名 import *

直接使用函数名即可. 没有命名空间. 但不建议, 有命名冲突的风险.

函数编写指南 (略)

介绍一些函数编码习惯与约定

Last Updated:
Contributors: jk