python序列数据类型与区别_Python序列类型

序列类型

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

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

序列类型可分为两大类:

容器序列

list、tuple、collections.deque等这些能存放不同类型的数据。

扁平序列

str、bytes、bytearray、memoryview、array.array等只能存放一种数据类型。

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

可变序列

list、collections.deque、bytearray、memoryview、array.array等。

不可变序列

str、bytes和tuple。

可变与不可变

但是str不是可变类型么?stra = strb + 'hello'这样的表达式不是很常用么?

其实并不是这样的,当你执行上面得表达式的时候,python会为重新创建新的对象,并将stra指向该对象。

stra = 'hello'

print (id(stra))

stra += 'world'

print (id(stra))

132518560

132503096

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

a = ['hello']

print(id(a))

a += ['world']

print (id(a))

a = a+['test']

print (id(a))

132840184

132840184

132953232

可以看到当执行+=操作时,可变类型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)

object at 0x07F0D900>

0

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

def generator_test():

for i in range(10):

yield i

print(type(generator_test()))

next(generator_test())

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 bisect

haystack = [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 array

tup = (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 collections

dq = 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值