本文为学习廖雪峰Python教程时,所做个人笔记,仅供参考交流。

其他内容可见在线手册:菜鸟教程:Python基础

Python基础


数据类型和变量

字符串,定义如 a = ‘ABC’,本质是拷贝的字符串指针给a;

a = 'ABC'
b = a
a = 'DEF'
print(b)

输出结果:ABC

多行输入,不用\n的方法

采用'''配对的方法,示例如下:

>>> print('''line1 ... line2 ... line3''')
line1
line2
line3

默认不用\\,\t, \n等转义输出:

print(r'''I'm ok''')
print('I\'m ok')
f = open(r'D:\workspace\l2hc_debug\mdct.txt')

在’string’前,加个r可以强制不用转义,按字符串内容本身处理。

浮点/整数运算

  • 整数除法: 10 // 3 => 3
  • 取余: 10 % 3 => 1
  • 其余正常都是按浮点运算进行
  • 如 3 / 2 => 1.5,结果是按浮点数运算

**的用法

  • 放在变量前,表示多少次方,如 2.0 ** 3.0,结果为8;功能类似于C语言中的 ^符号
  • 放在参数前,表示入参为字典,如 dealit(x, **args),第二个输入参数需为字典

小结:对变量赋值x = y是把变量x指向真正的对象,该对象是变量y所指向的。随后对变量y的赋值不影响变量x的指向。

字符串和编码


格式化输入输出总结

方法一:符号%

Python中,采用的格式化输出输出方式和C语言类似,用%实现,举例如下:

>>> 'Hello, %s' % 'world'
'Hello, world'
>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)
'Hi, Michael, you have $1000000.'
  • %d十进制整数
  • %f浮点数
  • %s字符串
  • %x十六进制整数
  • %%来表示一个%

方法二:字符串函数format()

>>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
'Hello, 小明, 成绩提升了 17.1%'
  • 1:.1f中的.1f表示按1位有效小数处理
  • 返回结果为字符串

字符串常用操作:

  • 分割切片,split(),字符串分割函数,不加入任何参数时,默认分离所有空格、空白符包括\n。

list和tuple


list特点

  • 是个数组列表,里面可以存浮点、整数、字符串等不同类型
  • list可以内部再嵌套list类型,实现多维数组
  • 类似C++的vector
  • 定义方式为num = []
  • 初始化举例:classmates = ['Michael', 'Bob', 'Tracy']

常用操作:

  • 取长度,len(xx),不仅限于list,可以针对任意对象
  • 引用,xx[0], xx[-1]
  • 追加,xx.append(’’),往列表末尾插入对象,注意一次只能一个元素
  • 插入,xx.insert(i, ‘’),往指定位置插入对象
  • 删除末尾,xx.pop()
  • 删除指定,xx.pop(i),删除指定位置i处的对象
  • 排序,xx.sort(),默认按字典序或数值升序

tuple特点

  • 元组,本质也是有序列表,区别在于定义后,不能改变,类似于C语言中的常量定义const list
  • 定义方式为t = (), 表示空元素
  • 仅1个元素的时候,定义t = (1,),依次类推
  • 初始化举例:classmates = ('Michael', 'Bob', 'Tracy')
  • 没有增删改操作,只有查操作

可变与不可变辨析:

  • 例1:

    >>> t = ('a', 'b', ['A', 'B'])
    >>> t[2][0] = 'X'
    >>> t[2][1] = 'Y'
    >>> t
    ('a', 'b', ['X', 'Y'])
    
  • 分析:t作为元组定义,只有t[0],t[1],t[2]是元组,而t[2]的内容定义是list,因为是用[]定义的,所以A/B都可以改变

  • 例2:

  • >>> a = 'abc'
    >>> a.replace('a', 'A')
    'Abc'
    >>> a
    'abc'
    
  • replace方***创建返回一个副本,a本身指向的内容不会变;a.replace()类似于C语言的右值

  • 改正后的方法:

  • >>> a = 'abc'
    >>> b = a.replace('a', 'A')
    >>> b
    'Abc'
    >>> a
    'abc'
    

条件判断


基础语法:

age = 3
if age >= 18:
    print('adult')
elif age >= 6:
    print('teenager')
else:
    print('kid')

相关用法:

  • s = input(“提示内容:xxx”),获取键盘输入的str
  • i = int(s),将字符串s转为整数

循环


基础语法:

for循环

names = ['Michael', 'Bob', 'Tracy']
for name in names:
    print(name)

while循环

sum = 0
n = 99
while n > 0:
    sum = sum + n
    n = n - 2
print(sum)

break中断:跳出最近一层循环

continue跳过:跳过当前,进入下轮循环

相关用法:

  • range(i),生成0到i-1的整数序列
  • list(range(i)),将该整数序列转为list

dict/set字典和散列


dict特点

  • 类似于C++的map,C的hash表
  • 涵盖关键词key和键值value
  • key最常用的是字符串,因为不好查找匹配

dict基础用法

  • >>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
    >>> d['Michael']
    
  • 上例中,key就是人名,value就是成绩

dict操作

  • 'Thomas' in d的in可以判断key是否存在,返回值为bool

  • d.get(‘name’),返回none的时候,交互环境不显示

  • d.get(‘Thomas’, -1),也是检查是否存在Thomas,指定若不存在返回-1,也可以指定其他值如-2/0等

  • d.pop(‘name’),弹出删除对应key

set特点

  • 和dic类似,不同之处在于set不存value,且不能有重复的key
  • 作用,类似于数学集合,可以做并集,交集等,返回的结果还是set类型
  • s.add(key),添加key
  • s.remove(key),移除key

函数用法


调用函数

常用函数

  • abs()
  • max(1, 2, 3, 3, 5, 9, 6, 1)
  • int(‘str’),字符串转成整数
  • float(‘str’),字符串转成浮点值
  • str(num),将数字转为字符串
  • bool(elment),判断元素(可以为数字、字符串、list等类型)的真假
  • hex(num),将十进制整数用十六进制输出,0xafbdf
  • isinstance(x, (int, float)),判断x元素的类型,若果是,则为true,否则为false
  • str.lower(),将字符串str转为小写
  • str.upper(),将字符串str转为大写

函数名的引用

  • a = abs
  • a(-1)
  • 输出为1,将abs的函数指针赋值给a,相当于给abs起了别名,调用实质还是abs

定义函数

demo用法

def my_abs(x):
    if x >= 0:
        return x
    else:
        return -x

空函数空语句

  • pass 相当于 C语言里面的 ;

  • 注意以下代码:

  • import math
    def quadratic(a, b, c):
        pass
        tmp = math.sqrt(b * b - 4 * a * c)
        x1 = (-b + tmp) / (2 * a)
        x2 = (-b - tmp) / (2 * a)
        return x1, x2
    
  • 分析:虽然有pass,记住它不是continue也不是return,只是个;,占位符,程序会继续运行后面的有效语句

函数返回值

  • 区别于C语言的是,Python可以有多个返回值

  • 但本质还是返回的一个tuple类型的元素,只是用多个元素来接收的话,左侧的可以tuple元素可以省略括号

小结

  • 定义函数时,需要确定函数名和参数个数
  • 如果有必要,可以先对参数的数据类型做检查;
  • 函数体内部可以用return随时返回函数结果;
  • 函数执行完毕也没有return语句时,自动return None
  • 函数可以同时返回多个值,但其实就是一个tuple。

函数参数

默认参数

  • 可以灵活的控制函数的入参,参数不够时,按默认配参输入

  • 如以下代码:

  • def power(x, n=2):
        s = 1
        while n > 0:
            n = n - 1
            s = s * x
        return s
    
  • 调用可以写:power(2),等价于power(2, 2)

注意事项

  • 必选参数在前,默认参数在后,否则会报错。(为啥要这样设计?因为默认参数在前面,你就不知道真正使用时第一个出现的参数是默认参数还是默认参数后面的参数)
  • 变化大的参数放前面,变化小的放后面
  • 对于确定的参数输入,优先赋值给必选参数

举例如下:

def power(n=2, k=1, x):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x + k
    return s
## 调用例子
power(5) ## 可以理解,前两个参数默认
power(1, 2) ## 这个1选择n/k那个是默认参数呢?
power(2, 2, 5) ## 参数充足,才清晰

说明:power(5)中,按逻辑还是把5优先给了后面的必选参数,所以为了一一对应,便于理解,默认将必选参数放在前面。

可变参数

  • 本质是个tuple

  • *numbers,表示将tuple指针解引用成每个元素

  • 示例如下:

  • def calc(*numbers):
        sum = 0
        for n in numbers:
            sum = sum + n * n
        return sum
    

关键词参数

  • 是个可选参数

  • 本质是dict,也即有key-value映射

  • **extra表示把extra 这个dict变量,作为关键词参数传入

  • 示例:

  • def person(name, age, **kw):
        print('name:', name, 'age:', age, 'other:', kw)
    
  • 进一步拓展,命名关键字参数,限定特定关键词参数传入

  • 示例:

  • def person(name, age, *, city, job): ## 参数不可变,固定需要传入四个参数
        print(name, age, city, job)
        
    ## or
    def person(name, age, *args, city, job): ## 参数可变
        print(name, age, args, city, job)
    

参数组合

  • 可任意组合,但有先后顺序
  • 必选参数、默认参数 -> 可变参数 -> 命名关键字参数和关键字参数
  • 总结辨析:
    • 可变参数:*args,本质tuple
    • 关键字参数: **kw,本质dict

递归函数

类似C语言定义,不赘述。

高级特性


切片

在list/tuple中访问任意片段或间隔规律的元素,注意访问下标是左闭右开[left, right)

示例如下:

  • s[:],显示所有元素
  • s[-1:],从-1到0,也即只显示最后一个元素
  • s[:10],从0开始到9,第10个元素不显示
  • s[2:10:3],从下标2到10,每间隔3个,取一个元素
  • s[-10:-1],从-10个元素,显示至倒数第二个元素,-1是截止,且为开

迭代

for xx in L:

列表生成式(本质:生成list)

[x * x for x in range(1, 11)]

[x * x for x in range(1, 11) if x % 2 == 0]

[x * x if x % 2 == 0 else -x * x for x in range(1, 11) ]

L = [m + n for m in "ABC" for n in "abc"]
print(L)

说明如下:

  • [x * x if x % 2 == 0 else -x * x || for x in range(1, 11) ]
  • ||将其划分两块,第一块写对列表元素的具体操作,第二块for相关,为元素循环过程
  • 语句2:可以在后面加入if判断,条件成立才做对应操作;但是最后的if不能再加入else
  • 可以在前面加入if判断,但是必须加入else分支
  • 可以嵌套,第二层for循环

生成器(本质:生成tuple)

  • 与列表生成式的唯一区别在于[],变为()
  • 减少list的空间浪费,边计算边生成
  • 方法二:yield声明
L = (x * x if x % 2 == 0 else -x * x for x in range(1, 11) )
print(L)

for x in L: ## 迭代时会更改L的地址
    print(next(L)) ## next访问也会更改L地址
    
for x in L:
    print(x) ## 能全部遍历

迭代器

  • 可用于for循环的:list/tuple/str/generator/dict/set等都是可迭代对象
  • 凡是可用于next()函数的对象,都是可迭代对象
  • 是否可迭代对象,由isinstance(xx, Iterable)的结果判断

遗留问题


函数参数一节测试中:

#!/usr/bin/python
## Write Python 3 code in this online editor and run it.
print("Hello, World!");

def mul(*args):
    res = 1
    for i in args:
      res = i * res
    return res

print('mul(5) =', mul(5))
print('mul(5, 6) =', mul(5, 6))
print('mul(5, 6, 7) =', mul(5, 6, 7))
print('mul(5, 6, 7, 9) =', mul(5, 6, 7, 9))
if mul(5) != 5:
    print('测试失败!')
elif mul(5, 6) != 30:
    print('测试失败!')
elif mul(5, 6, 7) != 210:
    print('测试失败!')
elif mul(5, 6, 7, 9) != 1890:
    print('测试失败!')
else:
    try:
        mul()
        print('测试失败!')
    except TypeError:
        print('测试成功!')

当时疑问,为何在mul()调用后,显示测试失败?

看随后的评论得到解答:

def mul(*num):
    if len(num) == 0:
        raise TypeError
    mult = 1
    for number in num:
        mult = mult * number
    return mult

或者这种方法:限制至少有一个可用参数,多余的为可变参数,若输入参数为0,肯定报出类型输入错误

def mul(x, *y):
  for i in y:
      x = x * i
  return x