range(5) -> 0、1、2、3、4
range(5,9) -> 5、6、7、8
range(0,10,3) -> 0、3、6、9 :步长为3
在内存中,序列是一块用来存储多个值的连续的内存空间。
一个对象包含:内存地址id,数据类型type,数值value三部分,序列中存储的是对象的id。
列表索引,从前往后,下标从0开始,从后往前,下标从-1开始。
list.append(obj)#在列表末尾添加新的对象list.extend(seq)#在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)list.count(obj)#统计某个元素在列表中出现的次数list.index(obj)#从列表中找出某个值第一个匹配项的索引位置list.insert(index, obj)#将对象插入列表index位置list.pop([index=-1])#移除列表中的一个元素(默认最后一个元素),并且返回该元素的值list.remove(obj)#移除列表中某个值的第一个匹配项list.sort( key=None, reverse=False)#对原列表进行排序list.clear()#清空列表list.copy()#复制列表,返回列表对象的浅拷贝list.reverse()#所有元素原地翻转
append()方法是原地增加元素,列表内存地址不变
>>> list2=[x**2 for x in range(10) if x&1==1]>>> list2[1, 9, 25, 49, 81]>>> id(list2)22112552>>> list2.append(2)>>>> list2[1, 9, 25, 49, 81, 2]>>> id(list2)22112552
+运算使用新内存地址,而+=运算仍使用原内存地址
>>> list3[1, 2, 3, 4, 5]>>> id(list3)22111464>>> list3+=[6]>>> list3[1, 2, 3, 4, 5, 6]>>> id(list3)22111464>>> list3=list3+[7]>>> list3[1, 2, 3, 4, 5, 6, 7]>>> id(list3)22069096
extend()方法是原地操作,内存地址不变。效率高于+运算的拼接操作。
>>> list3.extend([9,10])>>> list3[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]>>> id(list3)22069096
列表删除:
del 直接删除
del list[2]
pop() 删除并返回,如未指定位置,默认删除最后一个元素
>>> list4=[1,2,3,4]>>> list4[1, 2, 3, 4]>>> del list4[2]>>> list4[1, 2, 4]>>> list4.pop()4>>> list4[1, 2]
remove()方法,删除首次出现的指定元素,若不存在,抛出异常。
>>> list5=[1,2,3,4,5,4,3,2]>>> list5.remove(2)>>> list5[1, 3, 4, 5, 4, 3, 2]>>> list5.remove(6)Traceback (most recent call last): File "
列表索引:
index()方法,获取指定元素首次出现的位置,可指定搜索的起始地址。
def index(self, *args, **kwargs): # real signature unknown """ Return first index of value. Raises ValueError if the value is not present. """ pass >>>list1=[1,2,3,4,5,3,4,6]>>>print(list1.index(3,4))
不建新对象的列表排序:
>>> list6=[1,6,4,9,20,8,3]>>> id(list6)22112616>>> list6.sort()>>> list6[1, 3, 4, 6, 8, 9, 20]>>> id(list6)22112616>>> list6.sort(reverse=True)>>> list6[20, 9, 8, 6, 4, 3, 1]>>> id(list6)22112616
打乱顺序:
>>> import random>>> random.shuffle(list6)>>> list6[3, 8, 20, 4, 1, 6, 9]>>> id(list6)22112616
sorted()函数排序,生成新对象:
>>> list6=sorted(list6)>>> list6[1, 3, 4, 6, 8, 9, 20]>>> id(list6)22036296
列表推导式生成
cells = [(row,col) for row in range(1,10) for col in range(1,10)]#可以加两个循环,实际是个嵌套循环,cells列表包含9*9个元组
元组 元组中只包含一个元素时,需要在元素后面添加逗号‘ , ’,否则括号会被当作运算符使用。
元组可以使用下标索引来访问元组中的值。
元组中的元素值是不允许修改的,但我们可以对元组进行连接组合。
元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组。
len(tuple)#计算元组元素个数。max(tuple)#返回元组中元素最大值。min(tuple)#返回元组中元素最小值。tuple(iterable)#将可迭代系列转换为元组。
>>>list1= ['Google', 'Taobao', 'Runoob', 'Baidu']>>>tuple1=tuple(list1)>>>tuple1('Google', 'Taobao', 'Runoob', 'Baidu')
所谓元组的不可变指的是元组所指向的内存中的内容不可变。
不可变对象,如元组,其中若包含可变对象,如列表,则对列表内容的修改是合法的。元组中存放的是列表的内存地址,列表元素的改变并不改变其自身的地址。
元组排序只能用sorted()函数,且返回类型为列表>>> tup=(1,5,4,9,8,7,3,6)>>> id(tup)21784752>>> type(tup)
>>> list1=[1,2,3]>>> list2=[10,20,30]>>> list3=[100,200,300]>>> zip_tup=zip(list1,list2,list3)>>> type(zip_tup)
>>> (x for x in range(1,100) if x%0==0)
推导式得到的是生成器对象。
一个生成器只能运行一次。
>>> generator = (x for x in range(1,100) if x%3==0)>>> tup1=tuple(generator)>>> tup1(3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99)>>> tup2=tuple(generator)>>> tup2()
字典 访问字典里的值把相应的键放入到方括号中,如下实例:
tinydict = {'Name': 'xiaoming', 'Age': 10, 'Class': 'First'} print ("tinydict['Name']: ", tinydict['Name'])print ("tinydict['Age']: ", tinydict['Age'])
运行结果:
tinydict['Name']: xiaomingtinydict['Age']: 10
使用大括号 { } 创建空字典# 使用大括号 {} 来创建空字典emptyDict = {}# 打印字典print(emptyDict)# 查看字典的数量print("Length:", len(emptyDict))# 查看类型print(type(emptyDict))
运行结果:
{}Length: 0
tinydict = {'Name': 'xiaoming', 'Age': 10, 'Class': 'First'} tinydict['Age'] = 8 # 更新 Agetinydict['School'] = "一中" # 添加信息 print ("tinydict['Age']: ", tinydict['Age'])print ("tinydict['School']: ", tinydict['School'])
能删单一的元素也能清空字典,清空只需一项操作。显式删除一个字典用del命令tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'} del tinydict['Name'] # 删除键 'Name'tinydict.clear() # 清空字典del tinydict # 删除字典tinydict.pop('Name')#删除键值对,并返回值 print ("tinydict['Age']: ", tinydict['Age'])print ("tinydict['School']: ", tinydict['School'])
字典值可以是任何的 python 对象,既可以是标准的对象,也可以是用户定义的,但键不行。两个重要的点需要记住:
1)不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住
tinydict = {'Name': 'Lisa', 'Age': 26, 'Name': '丽莎'} print ("tinydict['Name']: ", tinydict['Name'])
运行结果:
tinydict['Name']: 丽莎
2)键必须不可变,所以可以用数字,字符串或元组充当,而用列表就不行,如下实例:
tinydict = {['Name']: 'Runoob', 'Age': 7} print ("tinydict['Name']: ", tinydict['Name'])
以上实例输出结果:
Traceback (most recent call last): File "C:/Users/11457/Desktop/pythonProject1/practise.py", line 1, in
len(dict)#计算字典元素个数,即键的总数。str(dict)#输出字典,可以打印的字符串表示。dict.update(dict2)#更新dict2的键值对到dict上
字典对象的核心是散列表。
字典的遍历操作与字典的修改操作分开,新增键值对可能导致字典扩容,键值对顺序重排。
字典推导式
>>> my_text='i love you,i love him,i love all people.'>>> char_count={c:my_text.count(c) for c in my_text}>>> char_count{'i': 4, ' ': 7, 'l': 6, 'o': 5, 'v': 3, 'e': 5, 'y': 1, 'u': 1, ',': 2, 'h': 1, 'm': 1, 'a': 1, 'p': 2, '.': 1}
有序哈希表中的键值对是按照插入顺序排序。Python 3.6 后,默认字典就是有序的,因此无需使用 OrderedDict()。 集合 集合的底层实现是字典,实际是字典中的键对象。
集合set1和set2:
并集
set1|set2
交集
set1&set2
差集
set1-set2
集合推导式生成
>>> set1={x for x in range(1,100) if x%11==0}>>> set1{33, 66, 99, 11, 44, 77, 22, 55, 88}
字符串字符串切片
s='abcdef'
>>> s[2:]'cdef'
>>> s[2:5]'cde'
>>> s[:-2]'abcd'
>>> s[::-1]'fedcba'
split()函数
>>> str='i am a teacher'>>> str 'i am a teacher'>>> str.split()['i', 'am', 'a', 'teacher']>>> str.split('a')['i ', 'm ', ' te', 'cher']
join()函数
>>> str=['as','bg','DG','Ui'] >>> '*'.join(str)'as*bg*DG*Ui'>>> ''.join(str) 'asbgDGUi'>>> ' '.join(str)'as bg DG Ui'
+操作字符串,有几个+,就生成几个新字符串对象,join()的性能好。
字符串驻留机制
>>> a='abc123'>>> b='abc123'>>> print(id(a),id(b))30500256 30500256
相关函数
>>> str1='我是mary,今天我来到这里,很开心。'>>> str1.startswith('我')#判断是否以'我'开始True>>> str1.endswith('心。')#判断是否以'心。'结束True>>> str1.find('我')#'我'第一次出现的位置0>>> str1.rfind('我')#'我'最后一次出现的位置9>>> str1.find('s')#查询不存在的字符的位置,返回-1-1>>> len(str1) #字符串长度 19>>> str1.isalnum()#字符串全是字母与数字False>>> str1.isalpha()#字符串全是字母False>>> str1.count('我')#统计'我'出现了几次2>>> ' acount number '.strip() #去除首尾空格'acount number'>>> ' acount number '.lstrip()#去除首部空格'acount number '>>> ' acount number '.rstrip()#去除尾部空格 ' acount number'>>> '**#$asdfghk%^*'.strip('*')#去除首尾'*''#$asdfghk%^'
大小写转换
>>> str2='i like my home' >>> str2.capitalize() #产生新字符串,首字母大写'I like my home'>>> str2.title() #产生新字符串,每个单词首字母大写'I Like My Home'>>> str2.upper()#产生新字符串,每个字母都大写'I LIKE MY HOME'>>> str3='I LIKE MY HOME'>>> str3.lower()#产生新字符串,每个字母都小写'i like my home'>>> str4='I LiKe My HouSE'>>> str4.swapcase()#产生新字符串,所有字母大小写改变'i lIkE mY hOUse'
字符串的格式化
format()函数
可变字符串 StringIO
>>> import io >>> s='hello,world'>>> sio=io.StringIO(s)>>> sio<_io.StringIO object at 0x017B8898>>>> sio.getvalue()'hello,world'>>> sio.seek(7)7>>> sio.seek(0) 0>>> sio.write('H') 1>>> sio.getvalue() 'Hello,world'
##运算符
|#按位或按位与^#按位异或~#按位翻转<<#左移位>> #右移位/#除//#整除+#数字相加;字符串拼接;列表、元组合并*#数字相乘;字符串复制;列表、元组复制
函数 在函数中使用全局变量,需要先用global声明。
局部变量的查询与访问速度高于全局变量。
python中一切皆对象,所有的参数传递都是‘引用传递’,没有‘值传递’。
b=[10,20,30]print("b:",id(b))def funcb(m): print("m:",id(m)) m.append(40)funcb(b)print(b)print('b:',id(b))
运行结果:
b: 25339368m: 25339368[10, 20, 30, 40]b: 25339368
传递不可变类型对象时,仍是引用传递,当函数内对该对象修改时,才创建新对象。
a=10print("a:",id(a))def funcb(m): print("m:",id(m)) m+=1 print("m:",id(m))funcb(a)
结果:
a: 1682950208m: 1682950208m: 1682950224
默认值参数应放在形参列表的后面部分。
浅拷贝与深拷贝 浅拷贝:不拷贝子对象的内容,只拷贝子对象的引用。
深拷贝:连子对象的内存页全部拷贝一份,对子对象的修改不影响源对象。
传递不可变对象时,如果发生拷贝(赋值时),是浅拷贝。
浅拷贝示例代码:
import copya=[10,20,[30,40]]b=copy.copy(a)print('a',a,id(a))print('b',b,id(b))b.append(50)b[2].append(0)print('---浅拷贝---')print('a',a,id(a))print('b',b,id(b))结果:```pythona [10, 20, [30, 40]] 29937256b [10, 20, [30, 40]] 29937064---拷贝---a [10, 20, [30, 40, 0]] 29937256b [10, 20, [30, 40, 0], 50] 29937064
深拷贝示例代码:
import copya=[10,20,[30,40]]b=copy.deepcopy(a)print('a',a,id(a))print('b',b,id(b))b.append(50)b[2].append(0)print('---深拷贝---')print('a',a,id(a))print('b',b,id(b))
结果:
a [10, 20, [30, 40]] 27446888b [10, 20, [30, 40]] 27446696---深拷贝---a [10, 20, [30, 40]] 27446888b [10, 20, [30, 40, 0], 50] 27446696
可变参数与强制命名参数 可变参数分为两种,其一为*param,收集实参至元组中;其二为**param,收集实参至字典中。
*param:
def func1(a,b,*c): print(a,b,c)func1(1,2,3,4,5,6,'a')
运行结果:
1 2 (3, 4, 5, 6, 'a')
**param:
def func1(a,b,**c): print(a,b,c)func1(1,2,name='zzq',age=19,school='dlut')
运行结果:
1 2 {'name': 'zzq', 'age': 19, 'school': 'dlut'}
嵌套函数 nonlocal 声明外层局部变量,之后可对其修改。
global 声明全局变量,之后可对其修改。
返回用yield不用return,函数返回一个生成器。
迭代器与可迭代性 迭代器:能用next()访问,并不断返回下一个值的对象。
Interable:可迭代性
Interaor:迭代器
集合类对象(list,str,tuple,dict)与生成器都是可迭代的,但未必都是迭代器。
iter()函数:将具有迭代性的对象变为生成器对象,可使用next()函数。
是特殊函数,创建时很特殊。
是函数式编程的重要方式。
创建闭包:
简单例子:
def funcOut(num1): def funcIn(num2): return num2+num1 return funcInif __name__ == '__main__': a=10 b=20 f=funcOut(a) print(type(f)) print(f(b)) print(f(100))
外部函数的局部变量,不会随着外部函数调用结束而消失。
闭包的特殊用途:
可以在不修改现有功能源码的前提下,增加新的功能。如:日志功能(统计访问事件,访问功能,写到日志文件),权限验证 外部声明
global:全局声明
nonlocal:外部声明
new()方法:创建对象,一般不需要重写
init()方法:初始化创建好的对象,一般需要自己重写
class Employee: def __init__(self,name,age): self.name=name self.__age=age#属性前加__,表示私有e=Employee('xiaoming',18)print(e.name)print(e._Employee__age)#类外部访问私有属性的格式
运行结果:
xiaoming18
父类的私有属性,子类也需要间接访问。
组合class A: def say(self): print('AAA')class B: def __init__(self,a): self.a=a a=A()b=B(a)b.a.say()
运行结果
AAA
模块与包__init__.py:包中模块首次被使用时,__init__.py模块会执行一次。