廖雪峰 Python教程 笔记一

#Python基本语法
Python的应用范围非常广,至少要分为:科学计算、脚本运维、爬虫、业务系统(web,部分云计算)等方向。
廖雪峰 Python教程的学习笔记
Python之所以简洁,主要感觉到的是它代码语法核函数上上没有拘泥于固定的几种格式,十分的灵活,定义出了各种语法操作(比如 a**b,a<b<c, try xxx with xxx),以及方便的函数等,像Java一定不采用符号操作,必须用字母写方法,C有符号不提供那么多方法。
###1、输入输出:input进行输入,print进行输出:
name = input('请输入')
print('hello', name)
input返回值即输入内容,可以传入提示内容
— 注意想要输入整数,使用age = input("请输入年龄:"), 因为Python无类型,所以默认输入的是字符串,如果这时直接对age按整数处理,就会报错。需要进行转型的处理
age = int(age)
print输出,可以传入多种类型的参数,字符串,字面量数值或者变量:
— print(‘abc’,‘def’) //输出abc def 其中的,相当于空格
print(‘abc’+‘def’) // 输出abcdef
— print()输出默认是带换行的,想要不换行,使用print(“xxx”, end = “”) 即可, 3.x的版本上
还有seq = xxx, 代表逗号分隔符是哪个

###2、数据类型及运算
Python的基本数据类型有:
Python是动态类型语言,定义变量时不用再前面加上类型名称,所以也没有类型声明,根据给出的值判断是什么类型。
1、空值 None 表示
2、布尔类型 True False表示
布尔类型的运算不用符号,用的是字母名称!!有点不科学了
and、or和not三种

3、整数 10,9,8 等
Python可以直接处理任意大小的整数,和C、Java语言不一样,
另外注意,用 / 表示浮点数除法,用 // 表示取整除(地板除),不管整数还是小数相除都会取向下整
4、浮点数
5、字符串
字符串可以使用’或"引起来,还可以用’’’ 三个单引号引起来,里面的内容可以直接换行
这里面的字符串和Java一样的内部结构,是不可变对象
如print(’’’ 第一行
第二行’’’)
就会输出
第一行
第二行
转义:在字符串内部使用\x 进行转义,一个为了方便的操作,在’或"或’’'引起来的字符串前面加上r,里面的转义的字符就不转义了

数据类型的转型见前面有age = int(age) 这样转型,用的函数法处理,没有像C或Java定义这门的语法

###3、字符串和编码:
Python默认使用Unicode进行编码,现代大多数的操作系统和语言都支持Unicode. Unicode 字符长度为2个字节,能表示的字符仍然有限,且可能可能浪费内存,于是后面出现你UTF-8,它是变长的,显然更为灵活。所以一般情况下,读入或写出数据时都是以UTF-8为标准。在内存中用数值表示字符,不同的编码码制不一样,同一个字符的数值不同,最后读出来的可能就是乱码。所以在程序中对字符进行编码转换,也就是将内存中的表示数值转换成对应码制中的表示数值。

3.1 字符与编码号转换
ord(‘A’) 获取某个字符的编码
65
chr(66) 将整数转换到对应的字符

3.2 字符串与byte转换
使用
"xxx".encode("yyy") encode characters to byte array use the given encoding, the result be printed is asicii or hex number
"xxx".decode("yyy") parse byte array to characters use the given encoding,
it can contains a paramter which is used to ingonor the a small part of wrong bytes.like "xxx".decode("yyy", errors='ignore') ; otherwise the method will report an error

3.3 代码格式
代码文件也要声明格式,写在代码中的字符才能被正确处理,可在源文件的开头加上注释,告诉python解释器,代码使用的格式,另外还必须要在编辑器或IDE中指定代码使用的格式才行
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

**3.4 字符串的基本方法 **
(1)len(‘xxx’) 返回字符串的长度,如果在前面加上(b’sdfsfsdfs’) 转换成了byte的形式,就会返回byte数组,可见可以直接使用len()方法,不用像Java一样一定要加上类名或者创建对象,那样格式化,Python的代码形式更为灵活。

(2)格式化输出,Python支持和C语言一样的格式化输出操作,有所优化,形式为
'Hello, %s' % 'world'
"%d * %d = %0d "%(i, j, i * j) 匹配多个
用%连接形参和实参即可,形式上更简洁了。 用%连接,很巧妙,代码的语法跳出了C那样的固定式的限制,显得灵活自由。
另一个,它的%s,就想print语句一样,可以格式化各种基本的数据类型。

# 打印9*9乘法表
for i in range(1, 10):
    for j in range(1, i+1):
        print("%d * %d = %0d "%(i, j, i * j), end='')
    print()

还可以使用字符串的format的方法,比如
'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
会输出
'Hello, 小明, 成绩提升了 17.1%'
格式为{d:xxx},d代表第几个参数,xxx代表附加处理

4. 集合:数组列表list和元组tuple、map的dict和集合set

Python数组也是很灵活的,它的集合类列表、字符串等,是可以直接判断相等的,里面所有的元素。

4.1 数组列表
** 定义和初始化 **
l = ['Michael', 'Bob', 'Tracy']
因为动态类型,所以列表里面可以放任意不同类型的数据,包括列表自身。比如:
L = ['Apple', 123, True]
s = ['python', 'java', ['asp', 'php'], 'scheme']
使用列表中列表相当于多维数组,用s[2][1]可以访问数组中的数组

**元素访问和修改 **
l[i] 访问第i个
l[-i] 访问倒数第ige
l[i] = x, 赋值
l.append(x); 末尾加入
l.insert(i, x); 插入
l.pop(); 删除最后一个
l.remove(i); 删除第i个

**4.2 元组 **
元组是不可变的数组,除了不可修改外,其它操作和数组基本一致,当然不可修改是指的它的元素指向的引用本身不能修改再指向其它,引用对应的对象内部是可以修改的。
一般情况下,能用tuple就用tuple,代码更安全,更高效。
初始化方法:
t=('sdsd', 5.4, 6, None);
注意的是定义单元素tuple要加上,写成
t=(5,);
不然如果是(5),那就变成数字5了。

4.3 相当于map的dict

定义和初始化:
dict的初始化有几种方法

d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
d = [(a,1), (b,2), (c,3)]
d = {a:1, b:2, c:3}
d = zip(a,b) # a, b代表两个列表

操作

d['Adam'];#访问:这种方式只能访问已经存在的值,不存在的访问会抛出KeyError错误,可以先用if x in d 判断
d.get('Thomas')
d.get('Thomas', -1) # -1 为默认值
d['Jack'] = 88 赋值
d.pop('Bob')

使用map的注意是其key值必须是不可变对象,不然放进去之后变了就乱了,就找不到了等。同Java字符串以及整数、浮点数等基本类型可行。
另外,由于是无类型的,所以Python的key可以是不同类型

对于下标式访问,d[xx],只能

4.4 set
创建方法
s={1,1,2,3} 这个和dict具有一致性,因为map就是set的转化
s = set([1, 2, 3])
s.add(4)
s.remove(4)
set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作,支持了
s1 | s2
s1 & s2

自然的在Python中也有浅拷贝和深拷贝,使用copy方法的时候要注意。

5.条件语句和循环语句

age = 3
if age >= 18:
    print('your age is', age)
    print('adult')
else:
    print('your age is', age)
    print('teenager')

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

几个不同:
(1) 用空格代替括号开始,:代表括号结束
(2) Python 使用缩进代替{}限定语句块,缩进结束,代表语句块结束。
(3)else if 协作elif

同样的,对于循环语句Python也采用同样的格式进行处理。
有2种写法:
names = [‘Michael’, ‘Bob’, ‘Tracy’]
for name in names:
for num in range(10): # 迭代 0 到 9 之间的数字
for num in range(10,20): # 迭代 10 到 19 之间的数字
for letter in ‘Python’: # 迭代字符串

while(n > 0)

多重判断或多重循环在里面加上语句即可。

##二、函数
###1、定义函数
1.1 基本定义
和循环一样,用:和缩进替代{},假设定义一个绝对值函数

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

如果在一个语句块中想什么也不做,使用pass,eg:

if a > 0:
   pass

如果不加pass的话会报错

返回语句,由于Python无类型,所以不用声明返回值得类型。因此,更进一步的,返回值得个数也可以不加限定了,使用Python的元组即tuple类型可以做到这点。

1.2 引用函数
你已经把my_abs()的函数定义保存为abstest.py文件了,那么,可以在该文件的当前目录下启动Python解释器,用from abstest import my_abs来导入my_abs()函数,注意abstest是文件名(不含.py扩展名);

1.3 参数类型检查
由于Python是无类型的,但是方法可能传入任何类型的参数进来,所以方法的定义中必须手动检查参数类型,否则就会出错。

def my_abs(x):
    if not isinstance(x, (int, float)):
        raise TypeError('bad operand type')
    if x >= 0:
        return x
    else:
        return -x

用内置函数 isinstance(x, (int, float,…))检查

2 函数的参数

函数也可以赋值给一个变量,
Python的函数参数较为灵活和复杂,有基本参数,默认参数,{可变参数,{关键字参数, 命名关键字参数}}。
2.1 默认参数
默认参数就是参数含有默认值,调用方法时可以对该参数传递值,也可不对改参数传递值。要求必须把必选参数放在参数序列前面,把默认参数放在参数序列的后面,这样便于编译器处理,也便于使用理解。
默认参数还可以在传参时指定传给谁,在前面加上参数名=xxx即可,表示将实参传递给哪个具体的形参,这样就可以不按定义的默认参数的顺序传递默认参数了。
eg:
print("xcxc", end ="")就是这种调用

使用默认参数可以达到增加函数扩展性和简洁性的效果,比如要对原来的函数增加一个参数,又不影响以前的调用代码,使用默认参数即可。

Python默认参数的坑 默认参数中的默认值是可变的!!!
加入定义方法时对默认参数赋的值是一个可变对象,比如

def  add_end(L=[]):
       L.append('END')
       return L

Python内部的处理应该是,在程序初始化是时候,创建一个对象X,并将它复制给L, 然后返回L。但是当你再次使用该函数时,内部不会再创建一个对象,而是使用最开始创建的那个对象X,所以当你第二次调用add_end()时,会有两个’END’,第n次调用时有n个’END’,为避免这种问题,所以默认参数默认值必须使用不可变对象

2.2 可变参数
可变参数,就是在方法中声明一个参数,此参数可以代表0-n个参数,这时可以传递0-N个参数进去,如果想传递集合进去,使用
l=set[“aaa”,“bbb”, ‘ccc’]
method(*l)
即可
可变参数在函数调用时会自动组装成一个tuple。

2.3 关键字参数
1、其实前面的可变长参数相当于传递一个列表到函数中,这里的关键字参数就相当于一个map到函数中,如下:

def person(name, age, **kw):
    print(name, age, kw)

person("小明", 5, country = "china", gender = "男")

m = {"country" : "china", "gender" : "男"}
person("小明", 5, **m)

可以看出,直接传递key = value的形式,或者传递组装好的map(前面加上 **)进去都行,直接传递的形式更为简洁

2.4 命名关键字参数
还有一种叫做命名关键字参数,和默认关键字参数比较类似,如下:

def person(name, age, *, city, job):
    print(name, age, city, job)

要表达命名关键字参数时,必须加一个间隔符用来表示后面的是关键字序列,也即key的序列,这个间隔符用*表示,或者一个可变参数也可代替

命名参数也可以有自己的默认值,就行默认参数一样,不同的是,命名参数传值时必须指明传给那个命名关键字,而默认参数不一定需要,并且所以的不含默认值得命名参数都需要有只,所以命名参数相对于默认参数的优点是,操作更为明确。

2.4 参数的组合
由于有多种参数,他们之间的组合就比较讲究了,不然使用起来很容易混乱和出错。
参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
虽然后面几种可以改变顺序,但是最好不要那样做,不然很容易混乱。
另外, 虽然可以组合多达5种参数,但不要同时使用太多的组合,否则函数接口的可理解性很差。
另外,函数还有这样的语法:
定义

def f1(a, b, c=0, *args, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

然后调用

>>> args = (1, 2, 3, 4)
>>> f1(*args)

如果在list的元素个数足够的情况下了,解释器会逐一取出list的项填入到函数参数中,(不够会报错),对于关键字参数,则使用dict有一样的语法。

##3、列表高级特性、操作
###3.1 切片
切片就是获取集合的一个子集

L = [1,2,3,4,5,6,7,8,9,10]

L[a:b]表示获取L的下标a到b-1之间的元素的集合,如果a或b无值,则表示从0开始或到最后一个。a,b 可以使用负号的,b>=a 时,返回空,a或者b不在范围内都没事。
还有,可以间隔取数,如
L[a🅱️n] 表示每间隔n个数取一个数出来。

3.2 迭代

(1)正如Java的迭代器,只有对象是可迭代的,就能使用迭代语句进行迭代

>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代

用上面的语句判断即可

迭代dict ,默认迭代的是key,使用d.values()可以迭代value,使用d.items(),可以迭代key-value对

使用enumerate(x)函数可以同时迭代下标和值
for i, value in enumerate([‘A’, ‘B’, ‘C’]):

(2)迭代器Iterator
区别,迭代器对象与可迭代对象是不一样的,Iterator提供next()方法,返回下一个值,此方法是惰性的,只会计算下一个值。通过Iterablde的iter方法获得他的一个Iterator对象。

3.3 列表生成式

Python的列表生成式,功能强大,丰富
L = [x * x for x in range(1, 11) if x % 2 == 0]
如上,使用一行表达式生成列表,range(a,b) 后面表示的是对元素的过滤方式,for前面加一个表达式,表示对元素的计算式,这样生成最终的列表。

对于Map等的,还可以使用多个变量,就更强大了。

还可以多层循环,需要计算时就将内层的变量都可以写到两端
[m + n for m in ‘ABC’ for n in ‘XYZ’]

3.4 生成器

用于生成有限或无限个元素,并不是一次生成,而是调用一次,生成一次。可以使用next(g)方法,让它生成下一个元素。也可以在for循环中使用。
创建生成器的方法:
(1)直接使用 g = (x * x for x in range(10)) 这种生成式,把生成列表时用的[]变成()括号,即可创建一个生成器,它不再是一个列表,不能使用列表相关的方法。而是按生成器的来使用。
(2)使用函数对象创建:
比如

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'

调用next()时,遇到yield就返回一次值,然后函数暂停在这里,下次再调用next()函数从这里开始执行,直到遇到下一个yield,然后暂停,返回值。显然,对于循环中的next(),会循环的遇到yield。
含有yield的函数可以称作生成器函数,调用它之后返回的是一个生成器,并不是普通的返回值。比如
m = fib(6);
next(m);
或者
m = fib(b).__next__ #其中的__next_是生成器函数拥有的一个属性
m()
这两种方法让生成器进行下一次执行
可以直接对列表进行相加拼接 如 l[0:2] + s[8:]

这里可看出,Python的函数是能记录状态的,这和C中的函数是不一样的。在Python中它的实质和对象是没有区别的

重点内容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章