C/C++转Python学习笔记

果然Python和C/C++系的语法差别很大。。在学了C/C++之后再学Python,有种当初从Pascal转C++的既视感,相比之下C/C++转Java感觉就简单多了。
这里记录一下学习Python的笔记,其中标注了部分Python与C/C++明显差别的用法。
其中大部分Python语法解释来源于Python语言程序设计

几个细节上的差别

  • 单行注释以#开头,多行注释以’’’开头和结尾
  • Python的变量必须要赋值,换言之,通过赋值创建变量
  • Python的变量名可以是中文
  • Python变量名大小写敏感
  • Python中有同步赋值 如交换: x, y = y, x
  • 引用库的两种方法
库调用方式 函数调用方式
import foo foo.test()
from foo import test / from foo import * test()

常见语句

条件与循环语句

  • if语句可以嵌套 if < expr >: elif < expr >: elif < expr >: else:

  • 循环控制语句

    • for循环 for i in range(n):
  • 注意for可以和else:配对,else后的语句在for语句执行结束(没有被break打断)后执行
  • break, continue语句,用法同C
  • 有些句子允许写到一行,如if x >= 0: break
  • Python有while循环但没有do-while循环

错误处理语句

1
2
3
4
5
6
7
8
9
10
11
12
try: 
< 语句 >
except < 错误代码一 >:
< 处理异常1语句 >
except < 错误代码二 >:
< 处理异常2语句 >
except:
< 处理其它异常语句 >
else:
< 无异常时执行的语句 >
finally:
< 无论有没有异常都要最后执行的语句 >

其它常见语句

max函数

  • max函数可以从多个(不限于两个)值中找出最大值,也可以直接找出tuple中的最大元素

占位语句

  • pass不做任何任务,只是用来占地方打标记的,往往用于自上而下的程序设计,之后一般会在pass语句的位置补全应有代码

with-as语句

with [语句1] as [变量名]:

  • with-as语句块适用于对资源j进行访问的场合,能够确保不管过程是否出现异常都能自动调用清理工作,如f.close()
    用法举例:
    1
    2
    with open(path, 'wb') as f: 
    f.write(r.content)

函数

def < 函数名 >(函数参数1, 函数参数2):

  • Python中的函数不需要定义返回类型,却可以返回任何类型,也可以返回多个值(类型为元组,可以用同时赋值的方法赋值给多个变量 如a, b = main(1, 2)
  • 可以直接写return或者写return None
  • Python中没有引用,也就是函数参数只有值形参,但对于列表类型,传递的是列表的地址,在函数中尝试改变列表元素将会影响原列表

常用的数据类型

基础数据类型及运算符

  • Python中的整数表示法
    • 十进制999 -999
    • 二进制0B101 0b101 –0b101
    • 八进制0O 0o
    • 十六进制0x 0X
  • 类型转换int() float() complex()复数
  • 判断类型type()
  • 判断类型是否相等isinstance(< type1 >, < type2 >)
  • 几个特殊的运算符 x//y整除(但是支持浮点数) x%y取模(同样支持浮点数) x\*\*ypow(x,y)求方(支持浮点数) abs(x)(支持浮点数) divmod(x,y)即(x//y,x%y)(这是个tuple类型)
  • 用==判断值是否相等,用 is 和 is not 判断是否为同一个对象(地址是否相同,注:Python中许多情况下值相同则地址相同),如a = [] b = []a == b为True,而a is b为False
  • Python中没有++但是有+=
  • 布尔表达式 and or not 优先级not > and > or
  • 非零整数和浮点数都会被认为是True,零则会被认为是False,非空字符串会被认为是真,空字符串会被认为是假,可以这么用:

    1
    2
    ans = input("Which flavor do you want? [vanilla]") 
    flavor = ans or 'vanilla'

    或者ans = input("Which flavor do you want? [vanilla]") or ''

字符串

表示与运算符

  • 字符串以单引号或双引号表示
  • 假设字符串长度为L,则字符串最后一位的下标为L-1或-1,可以拓展为-n为倒数第n位
  • 字符串子串可以用s[a:b]来表示[a,b) 如exam[0:-1], 0可以省略
  • 字符串运算符 +合并字符串 *重复字符串 如3*“sudo”或”sudo”*3 就是"sudosudosudo"

字符串外部函数

  • 计算字符串长度 len()
  • 强转成字符串 str()
  • 单个字符转ascii码 ord()
  • ascii码转单个字符 chr()

遍历字符串

  • 遍历下标 for i in range(len(lt)): 注意:不要忘了range()不能通过[]索引来改变单个字符
  • for < var > in < string >: 注意:对< var >的操作不会影响到原字符串

字符串类型成员函数

成员函数 功能
< string >.upper() 转大写
< string >.lower() 转小写
< string >.capitalize() 首字母大写
< string >.strip() 去掉字符串两边的空格去掉两边的指定字符(或子串)
< string >.split() 根据给定子串分割字符串(类型为list,如果参数缺省则根据白空格进行分割)
< string >.isdigit() 判断是不是全是数字
< string >.find() 返回给定子串出现的位置(子串第一个字母的位置)如果没找到返回-1
< string >.replace(str1, str2, max) 字符串替换,把str1替换为str2,max为最多替换次数,可以省略
< string1 >.join(< string2 >) 返回一个字符串,将string1作为string2每个字符的分隔符
< string >.join(< list >) 将list合并为一个字符串,用< string >中的内容分隔list的不同元素

元组类型(tuple)

  • 元组是包含多个元素的类型(元素类型可以不同),元素之间用逗号分隔 如 t1 = 123, 456, "hello"
  • 元组可以是空的 t2 = ()
  • 元组包含一个元素 t3 = 123,
  • 元组外侧可以使用括号也可以不用
  • 元组的元素还可以是元组,此时作为元素的元组外侧一定有括号
  • 注意(123)表示整形而(123,)或123,表示元组
  • tuple与tuple在某些情况是可以比较大小的,比较方式从左到右逐个元素比较
  • 可以通过索引的方式访问元组中的元素 如t3[0]
  • 元组定义后既不能更改也不能删除
  • 可以像字符串那样索引区间 如t[1:] 索引第2到最后一个元素
  • 可以使用+(连接)和* (重复)进行运算

列表类型(list)

  • 列表是有序的元素集合 a = [0,1,2,3]
  • list与list在某些情况是可以比较大小的,比较方式从左到右逐个元素比较
  • 列表元素可以通过索引访问单个元a[0]
  • 也可以取列表的一个子序列a[x,y](注意:这时候取得的序列可以为空,可以只有一个元素,但不会是元素本身)
  • +连接两个序列 *重复序列
  • len(< seq >)序列中元素个数(这个函数也用来计算字符串长度)
  • for < var > in < seq >: 枚举序列元素 注意:对< var >的操作不会影响到原序列
  • < expr > in < seq > 成员检查,判断< expr >是否在序列中,注意否定形式是< expr > **not in** < seq >

列表操作

成员函数 操作
< list >.append(x) 把元素x追加到列表的最后
< list >.sort() 将列表元素排序
< list >.reverse() 将列表元素反转
< list >.index() 返回第一次出现元素x的索引值
< list >.insert(i,x) 在i位置(的元素前)插入元素x
< list >.count(x) 返回元素x在列表中的数量
< list >.remove(x) 删除列表中第一次出现的元素x
< list >.pop(i) 取出列表中位置i的元素,并删除它

另:字符串可以通过< string >.split()函数拆分成列表

字典类型

基本操作

  • 字典类型类似于C++中的map
  • 创建 stu = {"102-2012": "John", "103-2012": "Peter"}
  • 为字典增加一项 stu["202-2011"] = "Susan"
  • 删除 del students["102-2012"]
  • 可以通过索引的方式增加项和更改项

字典的遍历

  • 遍历字典的键key
    • for key in dictionaryName.keys(): print(key)
  • 遍历字典的值value
    • for value in dictionaryName.values(): print(value)
  • 遍历字典的项(输出的item为tuple类型)
    • for item in dictionaryName.items(): print(item)
  • 遍历字典的key-value
    • 输出的item, value分别为键和值对应的类型
      • for item, value in adic.items(): print(item, value)
    • 输出的(item, value)为tuple类型
      • for (item, value) in adic.items(): print((item, value))
  • 判断一个键是否在字典中 in或者not in
  • 字典的标准操作符 - < > <= >= == != != and or not
  • 字典不支持拼接和重复操作

字典方法

成员函数及返回值类型 操作
keys():list 返回一个包含字典所有key的列表(其实是< dict_keys >,可以用来遍历)
values():list 返回一个包含字典所有value的列表 (其实是< dict_values >)
items():list 返回一个包含所有项的列表(< dict_items > )
clear():None 删除字典中所有的项目
get(key, val):value 返回字典中key对应的值,如果找不到则返回val,val可以缺省,此时若找不到则返回值为None
pop(key):val 删除并返回字典中key对应的值
update(< dict >):None 将两个字典合并 注意:如果< dict >中存在与原字典相同的键,则新键值会覆盖原键值

类的定义

  • class classname[(父类名)]:[成员函数]
  • __init__ 构造函数:初始化对象的各属性
  • __del__ 析构函数:销毁对象

输入输出

控制台输入输出

  • input()的返回值是str型,并且读不到回车
  • eval()可以把字符串转表达式来进行计算,经常用于处理input()返回的字符串
  • Python的print输出也可以直接用逗号分隔各个元素,输出时会自动在元素与元素之间加上空格,结尾自动加上回车print(a, b, c),如果不想结尾自动加回车,则要这样写:print(a, b, c, end = '')

格式化输出

.format()是字符串类型(这里的字符串是参数字符串)的一个成员函数,返回格式化处理后的字符串

基本格式

  • < 模板字符串 >.format(< 逗号分割的参数 >)
  • < 模板字符串 >由槽(左右大括号{})和普通字符组成,槽的用法类似于c中的printf
  • format中的参数从左到右标号0,1,2…槽中可以指定参数显示的位置 如{2}[0][1]
  • 要显示大括号应该使用两个大括号

槽中的格式控制信息

< 参数序号 >:< 填充字符 >< 对齐方式 >< 场宽 >< 逗号, >< .精度 >< 类型 >
以上参数可以省略,但是不允许调换参数出现顺序

  1. 其中填充字符与场宽举例 “{:+>20}” 其中+为填充字符,>表示右对齐,< 表示左对齐,^表示居中对齐
  2. 加上< 逗号, >可以给十进制输出的整形和浮点型添加千位逗号
  3. < .精度 >和C中的类似
  4. < 类型 >可以是d, b(二进制整型), o, x, X(字母大写的十六进制整型), c(ascii码对应的字符), f, e, E(用大写E表示的浮点型), %(百分比)

Python格式化输出时中文对齐的问题

一个中文字符宽度也被视作1,但场宽对齐补充空格时补充的是英文空格,因此中英文混输会导致对齐问题,一个解决方案是输出中文空格chr(12288),代码如下:

1
2
tplt = "{0:{3}^10}\t{1:{3}^10}\t{2:^10}" 
print(tplt.format("学校", "城市", "分数", chr(12288)))

文件操作

  • 打开文件 infile = open('test.txt', 'r')
  • 打开模式:
    • r只读 w只写 a附加到文件末尾 rb只读二进制文件 wb只写二进制文件 ab附加到二进制文件末尾 r+读写
    • 即使是二进制文件也可以直接读出来回车和tab(解码前),解码用< bytes >.decode('utf-8'),编码< str >.encode('utf-8') ,返回值为< bytes >类型
  • 读取一行infile.readline() 注意:这个函数会把回车也读进返回的字符串,如果读到文件结尾则会返回空字符串
  • infile.read()读取整个文件
  • infile.readlines()返回值为整个文件内容的字符串,每项是以换行符为结尾的一行字符串
  • 甚至可以用for来遍历文件,一次读取一行(也会读入回车):for line in infile:
  • 读取多行的一种做法:
    1
    2
    3
    4
    5
    6
    7
    line = infile.readline() 
    while line != '':
    for xStr in line.split(','):
    sum = sum + eval(xStr)
    count = count + 1
    print(eval(xStr), sum / count, sum)
    line = infile.readline()
  • outfile.write() 把含有文本数据或二进制数据块的字符串写进文件中
  • writelines() 针对列表操作,接受一个字符串列表作为参数,将它们写入文件,并且行结束符不会被自动加入

数学库与随机数库

数学库(math)

  • 圆周率pi 15位小数
  • 自然常数e 15位小数
  • ceil(x) x向上取整
  • floor(x) 向下取整
  • pow(x,y)
  • log(x) 以e为底
  • log10(x)
  • sqrt(x)
  • exp(x) e的x次幂
  • degrees(x) 将弧度值转换成角度值
  • radians(x) 将角度值转换成弧度值
  • sin(x) x是弧度值
  • cos(x) x是弧度值
  • asin(x) arcsinx x∈[-1.0, 1.0]
  • acos(x) arccosx x∈[-1.0, 1.0]
  • atan(x) arctanx x∈-1.0,1.0

随机数库(random)

  • seed(x) 给随机数一个种子值,默认为系统时钟
  • random() 生成一个[0, 1.0]之间的随机小数
  • uniform(a,b) 生成一个a到b之间的随机小数
  • randint(a,b) 生成一个a到b之间的随机整数
  • randrange(a,b,c) 随机生成一个从a开始到b以c递增的数
  • choice(< list >) 从列表中随机返回一个元素
  • shuffle(< list >) 将列表中元素随机打乱
  • sample(< list >,k) 从指定列表随机获取k个元素

·· / ·– ·· ·-·· ·-·· / ·–· · ·-· ··· ·· ··· - / ··- -· - ·· ·-·· / ·· / ·– ·· -·