Python序列类型

来源:互联网 发布:淘宝网十字绣架子 编辑:程序博客网 时间:2024/05/21 19:42

序列类型

本文是《流畅的Python》一书第二章的笔记。

Python内置了强大的数据结构,除了基本的数值类型和布尔值外,Python还有各种集合类型,包含了:序列(sequence)、映射(mapping)和集合(set)。

序列类型可分为两大类:

  1. 容器序列
    listtuplecollections.deque等这些能存放不同类型的数据
  2. 扁平序列
    strbytesbytearraymemoryviewarray.array只能存放一种数据类型

按照能否被修改还可以分为可变或不可变类型。

  1. 可变序列
    listcollections.dequebytearraymemoryviewarray.array等。
  2. 不可变序列
    strbytestuple

可变与不可变

但是str不是可变类型么?stra = strb + 'hello'这样的表达式不是很常用么?
其实并不是这样的,当你执行上面得表达式的时候,python会为重新创建新的对象,并将stra指向该对象。

stra = 'hello'print (id(stra))stra += 'world'print (id(stra))
132518560132503096

可以看到stra已经不是原来的那个stra了。下边再来看看可变类型。

a = ['hello']print(id(a))a += ['world']print (id(a))a = a+['test']print (id(a))
132840184132840184132953232

可以看到当执行+=操作时,可变类型list并未没有生成新的对象。但到了下边执行赋值操作时,还是重新生成了新的对象。

+= 和 = 赋值操作的区别

对于可变对象而言,+=操作并不会改变改变原对象,只是会就地操作。而对于不可变对象,Python会建立新的对象,并将其与当前变量关联。而=赋值操作则都会建立新的对象。

列表推导

列表推导可以方便的生成我们需要的列表格式。

# 生成从0到10的x的平方的列表a = [x*x for x in range(10)]print (a)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

甚至还可以用于多个for循环的情况。

colors = ['black', 'white']sizes = ['s', 'm', 'l']tshirts = [(color, size) for size in sizes                         for color in colors]print(tshirts)
[('black', 's'), ('white', 's'), ('black', 'm'), ('white', 'm'), ('black', 'l'), ('white', 'l')]

在列表推导中python会忽略换行。

生成器

生成器在形式上类似于列表推导,只是适用的范围更广,生成器还可以用来推导元组、数组等。当然,更大的差别是,生成器遵守了迭代器协议,可以逐个的产出元素,而不是像循环那样一次建立一个完整的迭代对象。要想写出生成器表达式,只需要将列表推倒的方括号换为圆括号就好。

tuple_a = (x*x for x in range(10))print(type(tuple_a))print(tuple_a)next(tuple_a)
<class 'generator'><generator object <genexpr> at 0x07F0D900>
0

另一种写出生成器的方法是利用yield关键字。一旦一个函数含有yield关键字,这个函数就变成了一个生成器。

def generator_test():    for i in range(10):        yield iprint(type(generator_test()))next(generator_test())
<class 'generator'>

0

sort()和sorted()方法

sort()方法用于就地排序一个列表,并返回None。注意只有列表类型可以调用这个方法

a = [10,8,1,3,5,7]a.sort()print(a)
[1, 3, 5, 7, 8, 10]

注意这个排序是原地排序,也就是说并不会创建对象的副本。而且方法返回None,并不是排序后的数组。

sorted()方法可以接受任意的可迭代对象作为参数,并返回排序后的列表。无论它接收什么可迭代的参数,都会返回列表。

a = [10,8,1,5,3,7]print(sorted(a))b = tuple(a)print(sorted(b))
[1, 3, 5, 7, 8, 10][1, 3, 5, 7, 8, 10]

这两个函数都有两个可选参数。reverse:设定为True,则按照降序排列。key:作为排序的依据,一个只有一个参数的函数。比如将其设定为key=len则按照字符串长度排序。

a = ['Hell', 'World', 'zzz', 'aaaaaaa']print (sorted(a, reverse=True, key=len))
['aaaaaaa', 'World', 'Hell', 'zzz']

bisect模块

bisect模块主要包含两个函数,bisect和insert。两个函数都是利用二分查找算法在有序序列中查找或插入元素。

bisect.bisect(haystack, needle)

在干草垛(haystack)中找针(needle)的位置,该位置保证把needle的值插入后序列仍为升序,并返回该位置的值。

import bisecthaystack = [1, 7, 9, 20, 25, 30, 32, 33]position1 = bisect.bisect(haystack, 12)position2 = bisect.bisect(haystack, 20)print(position1, position2)
3 4

在值相同的情况下,bisect将20插入到了原值的右边,也可以利用bisect_left函数插入到原值左边。

haystack = [1, 7, 9, 20, 25, 30, 32, 33]position = bisect.bisect_left(haystack, 20)print(position)
3

bisect.insort(seq, item)

把变量item插入到序列seq中,并且仍然保持原序列升序。

haystack = [1, 7, 9, 20, 25, 30, 32, 33]bisect.insort(haystack, 10)print (haystack)
[1, 7, 9, 10, 20, 25, 30, 32, 33]

这个方法类似于sort函数的就地排序,它将item插入到原序列后返回None。同样的,这个方法也可以利用insort_left将值插入到原序列相同值的左边。

数组

当需要一个只包含大量数字的序列时,可以使用数组,底层的C语言实现使得数组比列表更加高效。

array.array(typecode, seq),typecode指定转化为array的类型,一旦指定array类型就不可变。

typecode C类型 Python类型 ‘b’ signed char int ‘B’ unsigned char int ‘u’ - unicode ‘i’ signed char int ‘I’ unsigned char int ‘f’ float float ‘d’ double double
import arraytup = (1,2,3,4,5)arr = array.array('f', tup)print(arr)
array('f', [1.0, 2.0, 3.0, 4.0, 5.0])

collections.deque

collections.deque类是一个双向队列,可以从两端添加或者删除元素。

import collectionsdq = collections.deque(range(10), maxlen=10)   # 需要指定队列大小,且一旦指定,队列大小不可变print (dq)dq.appendleft(-1)   #从左边继续添加元素时,会把最右边的元素“挤掉”print (dq)
deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)deque([-1, 0, 1, 2, 3, 4, 5, 6, 7, 8], maxlen=10)

类似于列表,deque也可以进行pop、append、remove、clear等操作,不同的是deque对于appeed和pop这两种操作都提供了从左边操作的方法,即appendleft和popleft。

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 斐讯n1配置 雪佛兰乐驰1.0配置 远景x1配置 孤岛危机1配置 1加7t配置 ipad1参数配置 1加7配置 thinkpad x1配置 吉利s1配置 前s1抗原阳性 幽门阳性1个加号严重吗 her2是1十算阴还是阳性 单纯疱疹1型igm阳性 尿隐血阳性1十 单纯疱疹病毒1型lgg抗体阳性 单纯疱疹病毒1型igg抗体阳性 单纯疱疹病毒1型igg阳性 单纯疱疹病毒1型抗体igg阳性 单纯性疱疹病毒1型igg阳性 0可以做除数吗为什么 0不可以做除数还是被除数 0除于任何数都得0对吗 0能不能做除数 0可以当被除数吗 0可以作为除数吗 除数可以为0吗 0能做被除数吗 青城山都江堰1日游 墨青城臣服1广播剧全集 都江堰青城山1日游 1马币 1000马币 250台币 1000台币 马赫遥 卡格尔马赫 1马赫是多少千米每小时 迈克尔舒马赫 3马赫是一小时多少公里 高达w op1 1高达