文章目录
数据结构
所谓可变不可变,指的是对对象进行某种操作后得到的新对象是否仍是之前的那个。若是可变对象,这些操作都是在原对象的基础上进行的,而不可变对象则会构造一个新的对象作为返回值。
- 列表list:可变,有序
- 字符串:不可变,有序
- 元组:不可变,有序
- 字典:可变,无序(映射)
- 集合:可变、不可变均有,无序
列表list
- 索引、切片
- 合并(+)、重复(*)
- list.append(x)
- list.extend(iterable)
- 注意,虽然extend效果与==+类似,但extend无返回值==(none),直接修改原列表
- list.insert(i,x)
- list.remove(x) 删除列表中第一个值为x的元素
- list.pop(i) 删除指定位置的元素并返回,默认返回最后一个元素
- list.index(x) 返回第一个值为x的元素的索引,若未匹配到则会报错
- list.count(x) 计数元素x在列表中出现的次数
- 常用函数len、sum、min、max
- 排序sort、reverse(按照原有的顺序倒序存放)
列表的别名与复制
当a表示一个列表时,使b=a,两个变量都表示的同一个列表,b只是列表a的别名。
要想复制列表,可以使用全切片 b = a[ : ]
元组
对于编译器而言,括号并非元组的标志,逗号才是,也就是说只要加了逗号,编译器就会把这个变量认作元组,但编译器输出元组会自动加括号。
字典dict
字典用{}表示,一个字典由0个到多个键对值组成 a={键对值1,…}
键对值::
字典是可变类型,但是key必须是不可变类型,例如字符串,不能让list作为key,且同一个字典不能出现相同的key。
在字典容器中,key起到索引的作用。
- dict.keys():取所有键值
- dict.values():取所有value值
- dict.items():取所有键对值
- dict.get(key):取得key对应的value
集合set
集合为用{}括起来的一组元素。与字典类似
创建空集合的方法为set()而非{}
控制结构
python没有
if语句与真假判断
在python中,每个对象都有固有属性真或假,非假即真,数字零、空对象、None都是被认作假,其余皆为真
'''一般形式'''
if <条件>:
elif <条件>:
else:
'''三元表达式'''
'''格式:条件满足时的值/条件/不满足时的值'''
a = x if x==True else y
while
python中的while有else块,但只有循环正常结束时才会执行,被break打断不执行
while<条件>:
<语句>
else:
<语句>
for与可迭代对象
for循环可对所有可迭代对象中的元素进行迭代,元素迭代的顺序与其序列一致
for i in range(0,10)
'''range(start,end[,step]),包含start但不包含end!!'''
列表解析式
可以用于生成列表
列表=[表达式 for循环1 for循环2 … ]
b=[i for i in range(5)]
a=[(x,y) for x in range(2) for y in range(3)]
print(b)
print(a)
'''输出结果'''
[0, 1, 2, 3, 4]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]
生成器表达式
与列表解析式非常的相似,但是其得到的是一个生成器,是可迭代对象,即不能直接print,但可以使用for循环或者转为列表。
a=(i for i in range(5))
print(list(a))
'''results'''
[0, 1, 2, 3, 4]
生成器表达式的意义是节省内存,效率更高
函数
参数类型:
- 实参
- 位置参数
- 关键字参数
- 形参
- 普通形参
- *x类型
- **x类型
函数实参类型
实参:函数调用时实际传过去的值
形参:函数定义时的参数
- 位置参数:平时常用的传参方式,实参按照位置顺序依次传给形参
- 关键字参数:实参指定对应的形参传值,不考虑顺序
def sum(a,b):
return(a,b)
print(sum(b=3,a=4))
'''结果'''
(4, 3)
注意,如果同时存在位置参数和关键字参数,位置参数要写在关键字参数前面。
有默认值的形参
一般来说函数实参和形参是对应的,但当定义函数时为参数指定了默认值,调用函数时可以给出比定义更少的实参,设置了默认值的参数可给可不给。
'''注意:不允许有默认值的参数之后存在无默认值的参数'''
def func(x,y=2,z='cn') #有效
def func(x,y=2,z) #无效
未知数量的形参
当形参用*修饰时,例如*x,表示其形参接受的实参个数未知,甚至可以是0个,此时实参以元组的形式传给x。
'''未知数量形参和普通形参可以共存'''
'''但是实参优先赋值给已定义的形参'''
def func(y,*x):
print("y:",y)
print("x:",x)
print("x.type:",type(x))
func(1,2,3)
'''results'''
y: 1
x: (2, 3)
x.type: <class 'tuple'>
此外还有用**修饰,实参以字典的形式传给X
def func(**x):
print("x:",x)
print("x.type:",type(x))
func(a=1,b=2,c=3)
'''results'''
x: {'x': 1, 'y': 2, 'z': 3}
x.type: <class 'dict'>
参数的先后顺序
函数定义时,形参的顺序 :普通形参——有默认值形参——*X——**X。
函数调用时,实参的顺序:位置实参——关键字实参。
传参的优先级:
一般而言,关键字实参传参的优先级最高(但是**X传入的字典由于格式可能会与关键字实参冲突)
其次是普通参数,这俩结束后有多余的才轮到*x和**x
lamda表达式
lambda定义了一个匿名函数,其形式为 + 输入的参数 + :+返回值
'''以下两个s是等价的'''
'''注意,x是形参,没有实际意义'''
s=lambda x:x*x
def s(x):
return x*x
lamda可以配合key进行排序
'''对dat按照每个元素的第二个值排序'''
dat=[(a,1),(b,2),(c,3)]
'''这里相当于将dat的每个元素分别传给x'''
dat.sort(key=lambda x:x[1])
内置函数map
map(function,Seq)
Seq是一个可迭代对象,对每一个Seq的元素依次执行function,返回一个可迭代对象
function可以是内置函数,也可以是自定义的,也可以是lambda表达式
a=map(str,range(5))
b=map(lambda x:x*x,range(5))
print(list(a))
print(list(b))
'''results'''
['0', '1', '2', '3', '4']
[0, 1, 4, 9, 16]
内置函数filter
用于过滤不符合条件的元素。
格式与map相同,把Seq中的元素传给function,若返回值为false,则丢弃该元素,返回值为true,保留元素。最终返回一个可迭代对象
模块与包
模块导入的方式
import moduleName
import moduleName as moduleName2
from moduleName import func
from moduleName import *
前两种导入方式,调用模块的函数时格式为.,后两种方式调用时不用加模块名。大型工程不建议使用第四种。
创建多个模块后,可以将关联强的模块放入一个文件夹中,即python包,此时,模块的名为 .
类
类实例化成为对象,类中的变量称为属性,类中的函数称为方法。类对象使用==.==调用属性和方法
定义
类中的属性必须要有初值,初始属性可以设置在init方法中
class People:
name="none"
age=0
sex="none"
'''构造函数,注意,init两边是两个下划线组成的'''
def __init__(self,a,b,c):
self.name=a
self.age=b
self.sex=c
def getvalue(self):
return self.name
实例化
只有定义的类只是一个空壳,需要实例化才能创造具体的类对象
'''这种实例化方法,其内成员的属性均为默认值'''
p1 = People()
'''用构造函数指定成员对象数值'''
p2 = People(1,2,3)
self参数
self代表类对象本身,在两处地方要写
-
类中所有的方法的第一个形参必须是self(编译器一般会帮你写,但不要忘记)
-
在类的方法(函数)中访问属性(变量)时,要以self为前缀
继承和派生
一个类可以通过继承的方式获得另一个类的属性和方法
继承和派生其实都是一回事,只是说法不同罢了,即子类继承了父类,父类派生了子类。
class Student(people):
number = ""
'''重写__init__方法'''
def __init__(self,a,b,c,d):
people.__init__(self,a,b,c)
self.numbers=d
'''重写getvalue方法'''
def getvalue(self):
return self.number
子类中有与父类同名的方法时,子类对象调用该名称的方法时优先调用子类的方法,这称为方法的重写
子类调用父类构造函数
'''注意,这里调用people的__init__形参要包括self'''
people.__init__(self,a,b,c)
'''super()不写self形参'''
super().__init__(a,b,c)
多重继承
可以同时获得多个父类的属性和方法
class son(father1,father2):
''''''
注意,在父类中查找对应的属性和方法是按深度优先、从左到右的顺序的
文件处理
文件操作步骤:打开文件,读写操作,关闭文件
未关闭文件和文件数据读取异常均可能会导致报错
打开文件
open(),返回一个File对象,并由r、a、w三种方式
"a"和w"都能创建新文件,也可以是已有的文件
file = open("path")
file = open("path",'r') #注意 r也是要用引号引起来,r为只读
file = open("path",'w')#写文件
file = open("path",'a')#追加内容
读文件
所有的读取函数都是File对象的方法,并且都会读取空格和回车
- read()读取文件全部字符,返回字符串
- readline()读取一行,返回字符串
- readlines()读取全文件,返回字符串列表(一行为一个元素)
str1=file.read()
注意,当一个file对象被read()后,再次使用read()会读到空!
file1 = open("text")
str1 = file1.read()
str2 = file1.read()
print("str1",str1)
print("str2",str2)
#输出
1 hello world nmsl
2
其本质是因为随着文件读取,其光标也跟随移动,而read()函数将光标移到了末尾
这对其他两个也适用
file1 = open("text")
str1 = file1.readline()
str2 = file1.readline()
str3 = file1.readline()
print("1",str1)
print("2",str2)
print("3",str3)
#输出
1 get 1
2 get 2
3 #第三个readline()读了个寂寞
写文件
只有以w、a形式打开的文件才允许写
- file.write(string)
- file.writelines(list)
file1 = open("text1",'w')
file1.write("123456789")
file2 = open("text2",'w')
a=["nmd","wsm"]
file2.writelines(a)
关闭文件
file.close()
r1 = file1.readline()
str2 = file1.readline()
str3 = file1.readline()
print(“1”,str1)
print(“2”,str2)
print(“3”,str3)
#输出
1 get 1
2 get 2
3 #第三个readline()读了个寂寞
#### 写文件
只有以w、a形式打开的文件才允许写
+ file.write(string)
+ file.writelines(list)
```python
file1 = open("text1",'w')
file1.write("123456789")
file2 = open("text2",'w')
a=["nmd","wsm"]
file2.writelines(a)
关闭文件
file.close()