列表(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:会给键准备一个整数计数器,每次更新一个键的时候都会增加这个计数器。所以这个类型可以用来给散列表计数,
posted @ 2021-08-13 10:04  阿贝尔  阅读(366)  评论(0编辑  收藏  举报