列表(list)、元组(tuple)、字典(dict)
1.列表定义与列表推导
a=[1,2,3,'f']#列表定义,可以存放不同的数据类型 x = 'ABC' dummy = [ord(x) for x in x]#列表推导,返回一个列表
在列表中常用的sort与sorted方法的区别
sort方法会就地排序列表,即不会将列表复制一份后进行修改,而是直接对原始的列表进行修改;
sorted方法会将列表,复制一份后在对复制的列表进行修改,从而返回修改后的结果,可以保证原始输入列表不变。
以上两个方法都有两个可选的关键字参数:
- reverse:如果设置为True,排序后的元素列表以降序输出,默认Flase
- key:一个只有一个参数的函数,这个函数会被在序列中的每一个元素,所产生的结果将是排序算法依赖的对比关键字。比如说,在对一些 字符串排序时,可以用 key=str.lower 来实现忽略大小写的排序,或 者是用 key=len 进行基于字符串长度的排序。
fruits = ['grape', 'raspberry', 'apple', 'banana'] f=sorted(fruits) print(f)#['apple', 'banana', 'grape', 'raspberry'] print(fruits)#['grape', 'raspberry', 'apple', 'banana'],fruits不变 f1=sorted(fruits, reverse=True) print(f1)#['raspberry', 'grape', 'banana', 'apple'] fruits.sort() fruits#['apple', 'banana', 'grape', 'raspberry'],fruits改变
1.1.使用bisect来管理已排序的序列
bisect模块包含两个主要函数,bisect和insort,
- 使用bisect来搜索:该函数有两个参数:(排序的列表,要插入的值);返回该值插入位置下标
- bisect.insort:插入新元素,(排序数组,要插入的数)
import bisect HAYSTACK = [1, 4, 5, 6, 8, 12, 15, 20, 21, 23, 23, 26, 29, 30] index=bisect.bisect(HAYSTACK,9) print(index)#5 bisect.insort(HAYSTACK,9) HAYSTACK#[1, 4, 5, 6, 8, 9, 12, 15, 20, 21, 23, 23, 26, 29, 30]
1.2.collections.deque类(双向队列)
使用list.append和list.pop(0)联合起来可以用于模仿栈的“先进先出”的特点,但是删除列表的第一个元素(抑或是在第一个元素之前添加一个 元素)之类的操作是很耗时的,因为这些操作会牵扯到移动列表里的所有元素。
deque是一个线程安全、可快速从两端添加或删除元素的数据类型,在新建一个双向队列的时候,你可以指定这个队列的大小,如果这个队列满 员了,还可以从反向端删除过期的元素,然后在尾端添加新的元素。
from collections import deque dp=deque(range(10),maxlen=10) print(dp)#deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10) #队列的旋转操作接受一个参数 n,当 n > 0 时,队列的最右边的 n # 个元素会被移动到队列的左边。当 n < 0 时,最左边的 n 个元素会被 # 移动到右边。 dp.rotate(3) dp#deque([7, 8, 9, 0, 1, 2, 3, 4, 5, 6]) dp.append(100) dp #deque([8, 9, 0, 1, 2, 3, 4, 5, 6, 100]),将7丢掉 dp.pop()#返回100,将其从dp末尾移除 dp#deque([8, 9, 0, 1, 2, 3, 4, 5, 6]) dp.popleft()#返回8,将其从dp移除
2.元组与生成器表达式
元组的定义与列表类似,不过仅仅是将列表中的[]替换为()。
x=(1,2,3)#元组定义 a,b,c=x #元组拆包 print(a,b,c) d,*rest=x#用*来处理剩下的元素 print(d,rest)#1,[2,3]
2.1.命名元组---namedtuple
collections.namedtuple可以用来构建一个带有字段名的元组和一个有名字的类,
from collections import namedtuple ''' 命名元组的定义可以视为两个参数组成,第一个为类名,如下中的'City', 第二个参数为要为该元组设置不同位置的’名字‘,可以为字符串、列表 ''' City = namedtuple('City', 'name country population coordinates') tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667)) ''' 访问形式与一般元组类似,通过下标范围,但也可以通过为每个下标定义的’名‘访问,如 tokyo数组中tokyo[0]==tokyo.name ''' print(tokyo[0]) print(tokyo.name) ''' 可以通过._fields访问为该元组定义的所有字段(名) ''' print(tokyo._fields)#('name', 'country', 'population', 'coordinates') ''' 可以通过_asdict()将命名元组转换为collections.OrderDict形式,即将该元组转换为字典 ''' print(tokyo._asdict())#OrderedDict([('name', 'Tokyo'), ('country', 'JP'), ('population', 36.933), ('coordinates', (35.689722, 139.691667))])
元组是不可变类型,但若元组内包含了可变类型的变量,会导致该元组“可变”。
s=(1,2,[3,4]) s[2].append(5) print(s)#(1, 2, [3, 4, 5]) s[2][0]=21 print(s)#(1, 2, [21, 4, 5])
2.2.生成器表达式
生成器表达式与列表推导类型,不过是把[]换为(),并且生成器表达式返回的是生成器对象,通过遍历的方式获取生成器表达式中所有值
x = 'ABC' dummy = [ord(x) for x in x]#列表推导,返回一个列表 dummy2 = (ord(x) for x in x)#生成器表达式,返回一个生成器对象 print(dummy)#[65, 66, 67] print(dummy2)#<generator object <genexpr> at 0x0000016EDC7A2DC8> for i in dummy2: print(i)
3.dict
只有可散列类型才可以作为dict中的键,
如果一个对象是可散列的,那么在这个对象的生命周期中,其散列值是不变的,而且这个对象需要实现__hash__()方法,另外可散列对象还要有__eq__()方法。str、bytes 和数值类型都是可散列类型,frozenset也是可散列的。
一般来说用户自定义的类型的对象都是可散列的,散列值就是其id()函数返回的值。
字典的变种
- collections.OrderedDict:在添加键时保持顺序,因此键的迭代次序总是一样的
- collections.ChainMap:该类型可以容纳数个不同映射对象,然后在进行按键查找时,会将这些对象作为一个整体逐个查找
- collections.Counter:会给键准备一个整数计数器,每次更新一个键的时候都会增加这个计数器。所以这个类型可以用来给散列表计数,