『Python 干货』#1 基础语法(简明)

2021-10-22  本文已影响0人  Hwcoder

访问博客查看 本文 最新内容,排版更美观ヾ(•ω•`)o 如有错误欢迎指出~

Python 系列学习笔记:

跟着贵系的暑培过了一遍语法,然而写代码时还是感到乏力,总觉得要打一遍才能记住,于是有了这篇博客。

本文部分内容参考了清华 AYF 同学的教程,部分参考了 Python 官方的一份 Tutorial,函数用法参考了 xyfJASON 的博客。本文将持续更新。

Python 特性

相比于 C 的编译型、弱类型、静态类型特点,Python 则是一种解释型、强类型、动态类型的语言。

交互式 vs 脚本

作为一种解释型语言,Python 不需要像 C 一样编译运行,它可以逐行运行代码,因此又分为交互式窗口运行与脚本运行两种模式:

Hello World

>>> print('Hello, world!') # 打印输出
Hello, world!

在交互式窗口,>>> 作为提示符,在 IPython 中则是 In [1]:。执行 exit() 或者按下 Ctrl+D 就能退出窗口。

注意到,这行代码中没有 ; 分号,可以直接运行而无需编译,字符串用了单引号,注释用 # 开始【与 C 不同】。

简单数据类型

变量类型

【与 C 不同】,Python 不用声明变量类型,解释器自动解释。

需要单独说明的是,Python 会存储所有的 -5 到 256 的整数,其他任何变量是这些值时,会被指向这个预先开好的内存,因此任何两个值为 5 的 int 变量都指向同⼀内存地址。

尽量用小写变量名(下划线法),这是 Python3 的主流命名方式。

运算符

这里列出常见的运算符,运算符可以重载,重载需要修改其对应的定义函数。

算术运算符

比较运算符

位运算符:

赋值运算符

逻辑运算符

三目运算符

特殊条件运算符

字符串

Python 将字符串封装成了基本类型并处理了多种运算,带来许多便利,注意基本类型本身是不可修改的,所谓修改其实是将重新生成另一个字符串,再将其赋值给目标。

此外,Python 中没有单独的字符类型,单个字符将被视为长度为 1 的字符串。【与 C 不同】,可以用 "" 或者 '' 括起字符串。

下面是一些常用函数,设 str 是一个字符串:

此外还有一种跨行字符串,用 ’‘’”“” 括起来,由于脚本中顺序执行时不会输出变量值,这类字符串常用于跨行注释,特别是函数头注释。

输入输出与编码

此处说明几个重要函数:

最常用的输出语句 print,本质上是将变量转化为字符串输出,在末尾自动换行。该函数可以有多个变量,变量间用 , 分隔,输出时会用空格隔开。

如果要在一句话中插入许多变量,这条 print 语句可能会很丑陋,因此 Python 中有三种格式化字符串的方法。

其中 f-string 是 Python3.6 的新特性,最为直观便利。

此外,input('Press ENTER to continue') 是常见的一种输入语句,会显示对应的提示内容,读入内容以回车键结尾。

字节串

bytes 即是 Python 中的字节串,它表示最纯粹的二进制数据,【类似 C 的 unsigned char *】,但是在显示上它仅支持 ASCII 显示,因此用肉眼看显得有些不伦不类,通常它只存在于数据的处理过程中。

bytes 的构造与字符串类似,但是要加一个 b 做前导,如 print(b'\x41')

容器

Python 提供了一系列内置容器,它们如同 C++ 的 STL ⼀样,不过比 STL 的用法灵活得多。

同样先介绍几个重要函数:

列表 | List

列表(list)是很常用的容器,常被看作 Python 中的数组,但实际上【与 C++ 的 vector 类似】。设 lst 是一个列表:

基础操作

修改、添加、删除元素

组织列表

遍历列表

从头到尾遍历列表:for i in lst: 循环表达式

【与 C 不同】i 是列表元素,不是索引;循环结束后 i 停留为最后一个元素。

若要检查列表是否为空,可以用 if lst: 条件表达式,返回 bool

列表切片

元组 | Tuple

元组就是元素值不可修改(弱意义上的,其中元素的元素可以被修改)的列表。设 tpl 是一个元组:

基础操作

遍历元组

for i in tpl: 和列表一样

修改元组

元组中元素的值不能修改,但是元组变量本身可以被赋值,这点与字符串类似。此外,如果元组的中的元素是可修改的,如 List,

元组解包

经典的 Python 交换赋值代码:a, b = b, a,利用了解包和逗号构造

集合 | Set

集合由一组无序、互不重复的元素构成(在数学上也是如此),在内部用哈希实现。设 st 是一个集合:

基础操作

添加、删除元素

字典 | Dictionary

字典是一系列「键值对」,用于存储一组有穷映射,可将任何 Python 对象作为值,【类似于更高端版本的 C++ 的 map】。

基础操作

添加、修改、删除

遍历字典

迭代器

前文提到的所有容器,包括字符串、字节串都是可迭代的,这意味着它们可以用 for 循环来遍历,也可以用生成式构造(下面介绍)。

但最为特殊的迭代器是 range 类型,作为数值列表,与列表有相似之处,但它实际上不占用内存(用于大循环时很节省空间)。下面是一些常用方法:

生成式

使用生成式构造容器是非常常见、高效的操作,下面举几个例子:

综上所述,生成式表达可以用三段式:表达式 for 循环变量 in 迭代对象 if 筛选条件,其中最后的筛选条件不一定要。

流程控制

Python 中不用大括号来显式地分块,而是用冒号配合缩进。代码块与代码块之间至少隔着一个空行表示结束。当一个代码块必须存在,又不想写任何语句的时候,可以写一个 pass 作为占位符。

条件分支

a = 1
if a == 1:
    print('a is 1')
elif a == 0:
    print('a is 0')
else:
    print('wtf is a?')

注意,elifelse 后面也要有冒号配合缩进,如果有多个条件,用 andor 逻辑运算符连接。

for 循环

前面所列的容器、数值列表都可以用于 for 循环迭代,比较特别的是字符串也可以迭代:

a = 'hello world'
for c in a:
    print(c) # 竖着打印出 hello world,因为 print 自带换行

此外,如果在数值列表的迭代中用不到迭代变量 i,仅作为迭代次数使用,可以用 _ 变量表达。

while 循环

a = 10
while 2 <= a < 20:    # 语法糖,这种写法是被建议使⽤的
    print(a)
    a -= 1            # 注意 Python 中没有⾃增 1 和⾃减 1 运算符

跳出循环可以用 breakcontinue【与 C 相同】

函数

基础函数

def fib(n):
    """函数文档注释"""
    current, then = 0, 1
    for _ in range(n):
        current, then = then, current + then
    return current

fib(10) # 调用函数

函数传参

函数传参本质上和赋值号是一样的,都是浅复制(指针指向)【类似 C 的形参】。

传入参数的数量可以不固定,但是必须指定默认值;也可以调换顺序,但必须指明对象。

def add(a, b = 0):
    print(a + b)

add(1)              # 参数 b 采用默认 0
add(b = 2, a = 1)   # 调换顺序,指明对象

当然,也可以传递列表等容器,但传递的也是列表的地址,在函数中修改同样会改变原列表,如果不想修改原列表可以用 [:] 传递切片。

传递任意数量的参数

返回值

作为动态类型语言,函数返回值可以不固定,可以多个 return 在不同情况下返回不同值,或者没有 return(等价于 return None)。

函数模块调用

函数可以被存储在模块中被调用,模块是扩展名为 .py 的文件,包含函数的代码【类似于 C 的头文件】

所有 import 都放在程序开头【类似于 C++ 的 #include<>】。

Lambda 匿名函数

和很多语言⼀样,Python 中可以使用 Lambda 匿名函数完成一些简单的逻辑,但比较特殊的地方在于,Python 中匿名函数必须只由单个表达式构成,这个表达式的值也就是匿名函数的返回值。

lambda 关键字可以用来创建一个匿名函数,紧跟其后的是参数列表和用冒号 : 分割开的单个表达式。如,lambda x: 2 * x 是将任何输入的数乘 2,而 lambda x, y: x+y 是计算两个数字的和。

使用匿名函数的经验准则是保持简单以及只在本地使用一次。一种常见却不推崇的做法是将其作为简单函数的另一种声明方式,赋值给变量,如:

>>> doubler = lambda x: 2 * x
>>> doubler(5)
10
>>> type(doubler)
<class 'function'>

对 lambda 函数命名的唯一作用可能是出于教学目的,其问题在于这使得调试不那么直观——错误信息只会提示某个 lambda 函数存在问题,但不会提示哪个函数。

正确的做法应该是将其作为参数传递,如 .sort 函数、sorted 函数等,此时单个表达式会被计算为一个值并且参与后续的计算。

>>> integers = [(3, -3), (2, 3), (5, 1), (-4, 4)]
>>> sorted(integers, key=lambda x: x[-1])
[(3, -3), (5, 1), (2, 3), (-4, 4)]

>>> nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> nums.sort(key=lambda a: abs(5-a))
>>> nums
[5, 4, 6, 3, 7, 2, 8, 1, 9]

文件操作

读取文件

一种【与 C 相似】的操作是:

file = open('temp.txt', 'r')    # 打开一个文件,返回表示文件的对象
contents = file.read()          # 读取整个文件
print(contents)
file.close()                    # 关闭文件

此外,还有一种更推崇的操作方式,使用 with 上下文管理器,将打开的文件的对象存储在 as 后的变量,这样可以避免由于忘记关闭文件导致丢失数据:

with open('temp.txt', 'r') as file:
    contents = file.read()
    print(contents)

回到读取本身,方法 read() 读取整个文件的内容并返回单个字符串,并包含每个 \n 换行符。

但实际操作中读入一个长字符串是丑陋而且难以处理的,我们更倾向于逐行读入,用 line.rstrip() 消除行末的 \n

with open('temp.txt', 'r') as file:
    for line in file:   # file 也可作为一个迭代器
        print(line)     # 注意每一行末都会有一个 \n 被打印,而 print 本身又自带换行

另一种逐行读入是创建一个包含文件各行内容的列表,每个元素是一行内容的字符串,包含行尾的 \n

with open('temp.txt', 'r') as file:
    line1 = file.readline()     # 读入第一行作为字符串
    lines = file.readlines()    # 读入第二行以后的行(文件指针被移动了)

写入文件

with open('temp.txt', 'w') as file:
    file.write("I love programming.\n") # wirte 不会换行,要手动加

open() 函数的第二个实参 w 表示写入(自动创建或覆盖原内容),r 表示只读,a 表示附加(自动创建或添加到文件末尾),r+ 表示读写。如果不加第二个实参,则默认为 r 只读。

方法 write() 表示将字符串写入文件。如果要写入数值,应先用 str() 将其转化为字符串。

Python 中的类基础用法比 C/C++ 更简洁一些,待补充。

上一篇 下一篇

猜你喜欢

热点阅读