700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Python数据类型(三)数据结构类型—list tuple range set frozenset dict

Python数据类型(三)数据结构类型—list tuple range set frozenset dict

时间:2023-04-21 21:15:21

相关推荐

Python数据类型(三)数据结构类型—list tuple range set frozenset dict

数据结构类型是指用来存储数据、文字、字符、二进制、类对象,进一步方便操作查找存储内容的结构。数据类型分为了序列类型集合类型映射类型

序列类型是Python数据类型的内置基本数据类型,有三种基本序列类型:listtuplerange。同样,序列类型分为通用序列类型、可变类型和不可变类型。

集合类型是指由具有唯一性的hashable对象锁组成的无序多项集。无序多项集与序列类型不同,作为无序的集合并不支持记录元素的位置和插入顺序,相应地集合也不支持索引、切片或其他序列类的操作。目前有两种集合类型:setfrozenset

映射类型会将hashable值映射到任意对象,映射属于可变对象,目前只有一种标准映射类型对象:dic

序列类型-list,tupe,range

序列类型有通用序列,可变序列和不可变序列。序列支持一系列的操作。

通用序列操作支持

通用序列支持的操作可变序列和不可变序列都支持,下面是通用序列的支持操作:

备注:表格中s和t是具有相同类型的序列,n,i,j和k是整数,x是任何满足s所规定的类型和值限制的任意对象,序列的操作同样具有优先级顺序,表格是按照优先级降序排列(not in 和 in 优先级相同)

想同类型的序列支持比较,tuple和list的比较是通过比较对应元素的顺序,若比较结果相同,则每个元素比较结构都必须相等,并且两个序列长度必须相同。

可变序列操作支持

通用序列的操作在可变序列中适用,但可变序列也有部分自己的支持操作,可变序列的操作如下表所示:

备注:s是可变序列类型的实例,t是任意可迭代对象,x是符合对s所规定类型与值限制的任何对象

list - 列表

​ 列表是可变序列,通常用于存放同类项目的集合(其中精确的相似程度将根据应用而变化)。

list构建 以及list方法

列表的构建有多种方式

使用一对方括号来表示空列表:[]

使用方括号构建,列表中的项以逗号分割:[a,b,c]

使用列表推导式: [x for x in iterable]

使用类型构造器: list() 或list(iterable)。构造器将构造一个列表,其中的项与iterable中的项具有相同的的值与顺序。iterable可以是序列、支持迭代的容器或其它可迭代对象。 如果iterable已经是一个列表,将创建并返回其副本,类似于iterable[:]。 例如,list('abc')返回['a', 'b', 'c']list( (1, 2, 3) )返回[1, 2, 3]。 如果没有给出参数,构造器将创建一个空列表[]

其它操作,例如sorted()内置函数,分类后会产生一个列表。

列表作为序列类型,实现了所有通用序列和可变序列的操作,如下:

| 列表实现的序列操作 | 释 |

| —————————– | ———————————————————— |

| list.append(x) | 在列表的末尾添加一个元素。 |

| list.extend(iterable) | 使用可迭代对象中的所有元素来扩展列表 |

| list.insert(i,x) | 在给定的位置插入一个元素。第一个参数是要插入的元素的索引,所以a.insert(0, x)插入列表头部,a.insert(len(a), x)等同于a.append(x)|

| list.remove(x) | 若x在列表中存在,则将列表中的项的值为x的第一个元素移除 |

| list.pop(i) | 删除列表中给定位置的元素并返回它。如果没有给定位置,a.pop()将会删除并返回列表中的最后一个元素。 |

| list.clear() | 删除列表中所有的元素 |

| list.index(x, start, end) | 返回x出现的第一个索引位置,索引位置在start和end之间 |

| list.count(x) | 返回元素x在列表中出现的次数 |

| list.reverse() | 反转列表中的元素 |

| list.copy() | 返回列表的一个浅拷贝。相当于a[:]|

除了以上列表实现的序列操作之外,列表还增加了一个方法:

list.sort(*, key=None, reverse=False)

此方法会对列表进行原地排序,只使用<来进行各项间比较。 异常不会被屏蔽 —— 如果有任何比较操作失败,整个排序操作将失败(而列表可能会处于被部分修改的状态)。此外,sort()排序是稳定排序。

sort()接受两个仅限以关键字形式传入的参数:key指定带有一个参数的函数,用于从每个列表元素中提取比较键 (例如key=str.lower)。 对应于列表中每一项的键会被计算一次,然后在整个排序过程中使用。 默认值None表示直接对列表项排序而不计算一个单独的键值。

reverse为一个布尔值。 如果设为True,则每个列表元素将按反向顺序比较进行排序。

list方法代码示例:

>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']>>> fruits.count('apple')2>>> fruits.index('banana')3>>> fruits.index('banana', 4)6>>>#像 insert ,remove 或者 sort 方法,只修改列表,没有打印出返回值——它们返回默认值 None ,这是Python中所有可变数据结构的设计原则。>>> fruits.reverse()>>> fruits['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']>>> fruits.append('grape')>>> fruits['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']>>> fruits.sort()>>> fruits['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']>>> fruits.pop()'pear'>>>

列表作为栈和队列使用

列表的append和pop方法使得列表作为堆栈非常容易,最后一个插入,最先取出,这样完全符合栈的先进后出原则;要添加一个元素到堆栈的顶端,使用append()。要从堆栈顶部取出一个元素,使用pop(),不用指定索引。

>>> stack = [1,2,3,4]>>> stack.append(5)>>> stack.append(6)>>> stack[1, 2, 3, 4, 5, 6]>>> stack.pop()6>>> stack[1, 2, 3, 4, 5]>>> stack.pop()5>>> stack[1, 2, 3, 4]>>>

列表除了上述可以作为队列使用之外,还可以用作队列使用,其中先添加的元素被最先取出就完全符合队列的先进先出原则;然而列表用作这个目的相当低效,因为在列表的末尾添加和弹出元素非常快,但是在列表的开头插入或弹出元素却很慢 (因为所有的其他元素都必须移动一位),但若要实现一个队列,collections类中的deque可以快速的从两段操作。

列表推导式

列表推导式提供了一个更简单的创建列表的方法。常见的用法是把某种操作应用于序列或可迭代对象的每个元素上,然后使用其结果来创建列表,或者通过满足某些特定条件元素来创建子序列。

创建方式有–

普通方法:

>>> squares = []>>> for x in range(10):squares.append(x**2)>>> squares[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

上面的普通方法创建方式名为x的变量在for循环后仍然存在,可以利用lambda表达式解决该问题。

lambda表达式方法:

>>> squares = list(map(lambda x:x **2, range(10)))>>> squares[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

与lambda等效的还有一种更简化的方式。

>>> squares = [x**2 for x in range(10)]>>> squares[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

括号,其中包含一个表达式,后跟一个for子句,然后是零个或多个for或if子句的表达式形式也能创建列表

>>> [(x,y) for x in [1,2,3] for y in [3,1,4] if x!= y][(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

其等价于

>>> combs = []>>> for x in [1,2,3]:...for y in [3,1,4]:... if x != y:... combs.append((x, y))...>>> combs[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

列表推导式可以使用复杂的表达式和嵌套函数

>>> from math import pi>>> [str(round(pi, i)) for i in range(1,6)]['3.1', '3.14', '3.142', '3.1416', '3.14159']

嵌套列表推导式

列表推导式中的初始表达式可以是任何表达式,包括另一个列表推导式。

如下是3X4矩阵

>>> matrix = [[1,2,3,4], [5,6,7,8], [9,10,11,12],]

要想交换其行和列,写法如下:

>>> [[row[i] for row in matrix] for i in range(4)][[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

实际应用中,使用内置函数组成复杂的流程语句,zip()函数能高效的处理此种情况

>>> list(zip(*matrix))[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]

tuple ——元组

元组是不可变序列,通常用于存储异构数据的多项集(例如由enumerate()内置函数所产生的二元组),元组也被用于需要同构数据的不可变序列的情况(例如允许存储到setdict的实例)。

tuple元组构建

元组的构建有多种方式:

使用一对圆括号来表示空元组:()使用一个后缀逗号表示单元组:a,(a,)使用以逗号分隔的多个项:a, b, cor(a, b, c)使用内置的tuple():tuple()tuple(iterable)。tuple()构造器会构造一个元组,元组中的项与iterable中的项具有相同的值与顺序。iterable可以是序列、支持迭代的容器或其他可迭代对象。 如果iterable已经是一个元组,会不加改变地将其返回。 例如,tuple('abc')返回('a', 'b', 'c')tuple( [1, 2, 3] )返回(1, 2, 3)。 如果没有给出参数,构造器将创建一个空元组()

元组实现了通用序列的支持操作,所有通用序列支持的操作同样适合于元组,除了更改序列操作,元组作为不可变序列,是不支持修改其中元素的。

>>> t = 12345, 54321, 'hello!'>>> t[0]12345>>> t(12345, 54321, 'hello!')>>> u = t, (1,2,3,4,5)>>> u((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))>>> v = ([1,2,3], [3,2,1])>>> v([1, 2, 3], [3, 2, 1])>>> #序列解包>>> x,y,z = t>>> x12345>>> y54321>>> z'hello!'>>>

range类型

range类型表示不可变的数字序列,通常用于在for循环中指定次数。

range的构造需要调用系统模块函数:range(stop) 或range(start, stop, step)

​ range构造器参数必须为整数,(可以是内置的int或任何实现了__index__特殊方法的对象)。如果省略了step参数,则默认为1。 如果省略了start参数,默认值为0, 如果step为0则会引发ValueError;如果step为正值,确定ranger内容的公式为r[i] = start + step*i,其中i >= 0r[i] < stop;如果step为负值,确定range内容的公式仍然是i >= 0r[i] < stop,但限制条件改为i >= 0r[i] > stop。range 对象确实支持负索引,但是会将其解读为从正索引所确定的序列的末尾开始索引。range对象的元素绝对值大于sys.maxsize是被允许的。

>>> list(range(10))[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>>> list (range(1,11))[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]>>> list (range(0, 30, 5))[0, 5, 10, 15, 20, 25]>>> list (range(0,10,3))[0, 3, 6, 9]>>> list(range(0,-10,-1))[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]>>> list(range(0))[]>>> list(range(1,0))[]

range类型与listtuple相比,优势在于range对象总是占用固定数量的(较小)内存不论其所表示的范围有多大(因为它只保存了start,stopstep值,并会根据需要计算具体单项或子范围的值)。range提供包含检测、元素索引查找、切片等特性,并支持负索引 。

>>> r = range(0,20,2)>>> rrange(0, 20, 2)>>> 11 in rFalse>>> 10 in rTrue>>> r.index(10)5>>> r[5]10>>> r[:5]range(0, 10, 2)>>> r[-1]18>>>

集合类型——set、frozenset

目前有两种集合类型:setfrozenset

set类型

​ set类型是可变的, 其内容可以使用add()remove()这样的方法来改变,因为是可变的,所以没有哈希值,且不能呗用作字典的键或其它集合的元素。

​ set构建除了使用set构造器,非空的set还可以通过将以逗号分隔的元素列表包含于花括号之内来创建。

构造器方法:

set(iterable) :返回一个新的set对象,其元素来自于iterable。如果未指定iterable,则将返回一个新的空集合。

只适用于set的操作如下:

frozenset类型

frozenset类型是不可变的,并且能hashable,其内容在被创建后不能再改变,因此可以被用作字典的键值或其它集合的元素。

构造方法:

frozenset(iterable): 返回一个新的frozenset对象,其元素来自于iterable。集合的元素必须为hashable。 要表示由集合对象构成的集合,所有的内层集合必须为frozenset对象。 如果未指定iterable,则将返回一个新的空集合。

set和frozenset共同支持的操作

set和frozenset的实例提供以下操作:

set 和 frozenset示例:

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}>>> print (basket){'pear', 'banana', 'apple', 'orange'}>>> 'orange' in basketTrue>>> 'crabgrass' in basketFalse>>> a = set('abracadabra')>>> b = set('alacazam')>>> a{'r', 'c', 'a', 'd', 'b'}>>> a - b{'r', 'b', 'd'}>>> a | b{'r', 'c', 'a', 'd', 'b', 'z', 'l', 'm'}>>> a & b{'c', 'a'}>>> a ^ b{'r', 'd', 'b', 'z', 'l', 'm'}>>> #集合同样支持推导形式>>> a = [x for x in 'abracadabra' if x not in 'abc']>>> a['r', 'd', 'r']>>>

setfrozenset总结:

(1)setfrozenset均支持集合与集合的比较。两个集合当且仅当每个集合中的每个元素均包含于另一个集合之内(即各为对方的子集)时则相等。 一个集合当且仅当其为另一个集合的真子集(即为后者的子集但两者不相等)时则小于另一个集合。 一个集合当且仅当其为另一个集合的真超集(即为后者的超集但两者不相等)时则大于另一个集合。

(2)由于集合仅定义了部分排序(子集关系),因此由集合构成的列表list.sort()方法的输出并无定义。

(3) 集合的元素,与字典的键类似,必须为hashable

(4) 混合了set实例与frozenset的 二进制位运算将返回与第一个操作数相同的类型。例如:frozenset('ab') |set('bc')将返回frozenset的实例。

(5) 要创建一个空集合你只能用set()而不能用{},因为后者是创建一个空字典

映射类型 ——dict

dict字典是目前唯一的映射类型,字典的键值可以是任何值,除了非 hashable的值(包含列表、集合、字典或其他可变类型的值)。数字类型用作键时遵循数字比较的一般规则:如果两个数值相等 (例如11.0) 则两者可以被用来索引同一字典条目。 (但是,由于计算机对于浮点数存储的只是近似值,因此将其用作字典键是不明智的,这点在讲数字类型的时候提及过)

​ 字典可以通过将以逗号分隔的键: 值对列表包含于花括号之内来创建,例如:{'jack': 4098, 'sjoerd': 4127}{4098: 'jack', 4127: 'sjoerd'},也可以通过dict构造器来创建。

dict构建

dict构造器

dict(**kwarg)

dict(mapping, **kwarg)

dict(iterable, **kwarg)

以上构造器方法都返回一个新的字典,基于可选的位置参数和可能为空的关键字参数集来初始化。如果没有给出位置参数,将创建一个空字典。 如果给出一个位置参数并且其属于映射对象,将创建一个具有与映射对象相同键值对的字典。 否则的话,位置参数必须为一个iterable对象象。 该可迭代对象中的每一项本身必须为一个刚好包含两个元素的可迭代对象。 每一项中的第一个对象将成为新字典的一个键,第二个对象将成为其对应的值。 如果一个键出现一次以上,该键的最后一个值将成为其在新字典中对应的值。如果给出了关键字参数,则关键字参数及其值会被加入到基于位置参数创建的字典。 如果要加入的键已存在,来自关键字参数的值将替代来自位置参数的值。

>>> a = dict(one=1, two=2, three=3)>>> b = {'one':1, 'two':2, 'three':3}>>> c = dict(zip(['one', 'two', 'three'], [1,2,3]))>>> d = dict([('two', 2), ('one',1), ('three', 3)])>>> e = dict({'three':3, 'one':1, 'two':2})>>> a ==b == c == d ==eTrue

dict支持的操作

dict支持的操作如下:

dict代码示例

>>> tel = {'jack':4098, 'space':4139}>>> tel['guido'] = 4127>>> tel{'jack': 4098, 'space': 4139, 'guido': 4127}>>> tel['jack']4098>>> del tel['space']>>> tel['irv']=4127>>> tel{'jack': 4098, 'guido': 4127, 'irv': 4127}>>> list(tel.keys())['jack', 'guido', 'irv']>>> sorted(tel.keys())['guido', 'irv', 'jack']>>> 'guido' in telTrue>>> 'jack' not in telFalse>>> # 字典同样支持推导式>>> {x: x**2 for x in (2,4,6)}{2: 4, 4: 16, 6: 36}

数据结构类型循环过程优化

1.对于字典,循环过程中,可以用items()方法将关键字和对应的值同时取出

>>> for k, v in tel.items():print(k, v)jack 4098guido 4127irv 4127

2.单个序列循环时,可以用enumerate()函数将索引位置和其对应的值同时取出

>>> for i, v in enumerate(['tic', 'tac', 'toe']):print (i, v)0 tic1 tac2 toe

3.两个或多个序列中循环时,可以用zip()函数将其内元素一一匹配

>>> questions = ['name', 'quest', 'favorite color']>>> answers = ['lancelot', 'the holy grail', 'blue']>>> for q, a in zip(questions, answers):print ('what is your{0}? It is {1}.' .format(q, a))what is yourname? It is lancelot.what is yourquest? It is the holy grail.what is yourfavorite color? It is blue.

4.当逆向循环一个序列时, 先正向定位序列,然后调用reversed()函数

>>> for i in reversed(range(1, 10, 2)):print (i)97531>>>

5.如果要按某个顺序循环一个序列,可以用sorted()函数,它可以在不改动原序列的基础上返回一个新的排好序的序列

>>> for f in sorted(set(basket)):print (f)applebananaorangepear

6.若想在循环时修改列表内容,一般改为创建一个新列表

>>> import math>>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]>>> filtered_data = []>>> for value in raw_data:if not math.isnan(value):filtered_data.append(value)>>> filtered_data[56.2, 51.7, 55.3, 52.5, 47.8]>>>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。