利用 Python 进行数据分析——第3章 Python的数据结构、函数和⽂件

本文介绍了Python中的元组和列表,包括它们的创建、访问、修改特性。元组是不可变序列,而列表是可变的。内容涵盖了元组和列表的创建、索引、连接、排序、切片以及常用方法,如`count`、`sort`、`extend`、`insert`等。此外,还讨论了`zip`和`sorted`函数的用法。
摘要由CSDN通过智能技术生成

大都是书里面的内容,做个摘抄

元组是⼀个固定⻓度,不可改变的Python序列对象。创建元组的
最简单⽅式,是⽤逗号分隔⼀列值:

In	[1]:	tup	=	4,	5,	6
In	[2]:	tup
Out[2]:	(4,	5,	6)

当⽤复杂的表达式定义元组,最好将值放到圆括号内,如下所
示:

In	[3]:	nested_tup	=	(4,	5,	6),	(7,	8)
In	[4]:	nested_tup
Out[4]:	((4,5,	6),	(7,	8))

⽤tuple可以将任意序列或迭代器转换成元组:

In	[5]:	tuple([4,	0,	2])
Out[5]:	(4,	0,	2)

In	[6]:	tup	=	tuple('string')
In	[7]:	tup
Out[7]:	('s',	't',	'r',	'i',	'n',	'g')

可以⽤⽅括号访问元组中的元素。和C、C++、JAVA等语⾔⼀
样,序列是从0开始的:

In	[8]:	tup[0]
Out[8]:	's'

元组中存储的对象可能是可变对象。⼀旦创建了元组,元组中的
对象就不能修改了:

In	[9]:	tup	=	tuple(['foo',	[1,	2],	True])
In	[10]:	tup[2]	=	False
---------------------------------------------------------------------------
TypeError																																	Traceback	(most	recent	call	last)
<ipython-input-10-c7308343b841>	in	<module>()
---->	1	tup[2]	=	False
TypeError:	'tuple'	object	does	not	support	item	assignment

如果元组中的某个对象是可变的,⽐如列表,可以在原位进⾏修
改:

In	[11]:	tup[1].append(3)
In	[12]:	tup
Out[12]:	('foo',	[1,	2,	3],	True)

可以⽤加号运算符将元组串联起来:

In	[13]:	(4,	None,	'foo')	+	(6,	0)	+	('bar',)
Out[13]:	(4,	None,	'foo',	6,	0,	'bar')

元组乘以⼀个整数,像列表⼀样,会将⼏个元组的复制串联起
来:

In	[14]:	('foo',	'bar')	*	4
Out[14]:	('foo',	'bar',	'foo',	'bar',	'foo',	'bar',	'foo',	'bar')

对象本身并没有被复制,只是引⽤了它。
拆分元组
如果你想将元组赋值给类似元组的变量,Python会试图拆分等号
右边的值:

In	[15]:	tup	=	(4,	5,	6)
In	[16]:	a,	b,	c	=	tup
In	[17]:	b
Out[17]:	5

即使含有元组的元组也会被拆分:

In	[18]:	tup	=	4,	5,	(6,	7)
In	[19]:	a,	b,	(c,	d)	=	tup
In	[20]:	d
Out[20]:	7

使⽤这个功能,你可以很容易地替换变量的名字,其它语⾔可能
是这样:

tmp	=	a
a	=	b
b	=	tmp

但是在Python中,替换可以这样做:

In	[21]:	a,	b	=	1,	2
In	[22]:	a
Out[22]:	1
In	[23]:	b
Out[23]:	2
In	[24]:	b,	a	=	a,	b
In	[25]:	a
Out[25]:	2
In	[26]:	b
Out[26]:	1

变量拆分常⽤来迭代元组或列表序列:

In	[27]:	seq	=	[(1,	2,	3),	(4,	5,	6),	(7,	8,	9)]
In	[28]:	for	a,	b,	c	in	seq:
			....:					print('a={0},	b={1},	c={2}'.format(a,	b,	c))
a=1,	b=2,	c=3
a=4,	b=5,	c=6
a=7,	b=8,	c=9

Python最近新增了更多⾼级的元组拆分功能,允许从元组的开
头“摘取”⼏个元素。它使⽤了特殊的语法*rest,这也⽤在函数
签名中以抓取任意⻓度列表的位置参数:

In	[29]:	values	=	1,	2,	3,	4,	5
71
In	[30]:	a,	b,	*rest	=	values
In	[31]:	a,	b
Out[31]:	(1,	2)
In	[32]:	rest
Out[32]:	[3,	4,	5]

rest的部分是想要舍弃的部分,rest的名字不重要。作为惯⽤写
法,许多Python程序员会将不需要的变量使⽤下划线:

In	[33]:	a,	b,	*_	=	values

因为元组的⼤⼩和内容不能修改,它的实例⽅法都很轻量。其中
⼀个很有⽤的就是count(也适⽤于列表),它可以统计某个值
得出现频率:

In	[34]:	a	=	(1,	2,	2,	2,	3,	4,	2)
In	[35]:	a.count(2)
Out[35]:	4

列表
与元组对⽐,列表的⻓度可变、内容可以被修改。你可以⽤⽅括
号定义,或⽤list函数:

In	[36]:	a_list	=	[2,	3,	7,	None]
In	[37]:	tup	=	('foo',	'bar',	'baz')
In	[38]:	b_list	=	list(tup)
In	[39]:	b_list
Out[39]:	['foo',	'bar',	'baz']
In	[40]:	b_list[1]	=	'peekaboo'
In	[41]:	b_list
Out[41]:	['foo',	'peekaboo',	'baz']

列表和元组的语义接近,在许多函数中可以交叉使⽤。
list函数常⽤来在数据处理中实体化迭代器或⽣成器:

In	[42]:	gen	=	range(10)
In	[43]:	gen
Out[43]:	range(0,	10)
In	[44]:	list(gen)
Out[44]:	[0,	1,	2,	3,	4,	5,	6,	7,	8,	9]

添加和删除元素
可以⽤append在列表末尾添加元素:

In	[45]:	b_list.append('dwarf')
In	[46]:	b_list
Out[46]:	['foo',	'peekaboo',	'baz',	'dwarf']

insert可以在特定的位置插⼊元素:

In	[47]:	b_list.insert(1,	'red')
In	[48]:	b_list
Out[48]:	['foo',	'red',	'peekaboo',	'baz',	'dwarf']

插⼊的序号必须在0和列表⻓度之间。
警告:与append相⽐,insert耗费的计算量⼤,因为对后续
元素的引⽤必须在内部迁移,以便为新元素提供空间。如果
要在序列的头部和尾部插⼊元素,你可能需要使
⽤collections.deque,⼀个双尾部队列。
insert的逆运算是pop,它移除并返回指定位置的元素:

In	[49]:	b_list.pop(2)
Out[49]:	'peekaboo'
In	[50]:	b_list
Out[50]:	['foo',	'red',	'baz',	'dwarf']

可以⽤remove去除某个值,remove会先寻找第⼀个值并除去:

In	[51]:	b_list.append('foo')
In	[52]:	b_list
Out[52]:	['foo',	'red',	'baz',	'dwarf',	'foo']
In	[53]:	b_list.remove('foo')
In	[54]:	b_list
Out[54]:	['red',	'baz',	'dwarf',	'foo']

如果不考虑性能,使⽤append和remove,可以把Python的列表
当做完美的“多重集”数据结构。
⽤in可以检查列表是否包含某个值:

In	[55]:	'dwarf'	in	b_list
Out[55]:	True

否定in可以再加⼀个not:

In	[56]:	'dwarf'	not	in	b_list
Out[56]:	False

在列表中检查是否存在某个值远⽐字典和集合速度慢,因为
Python是线性搜索列表中的值,但在字典和集合中,在同样的时间内还可以检查其它项(基于哈希表)。
串联和组合列表
与元组类似,可以⽤加号将两个列表串联起来:

In	[57]:	[4,	None,	'foo']	+	[7,	8,	(2,	3)]
Out[57]:	[4,	None,	'foo',	7,	8,	(2,	3)]

如果已经定义了⼀个列表,⽤extend⽅法可以追加多个元素:

In	[58]:	x	=	[4,	None,	'foo']
In	[59]:	x.extend([7,	8,	(2,	3)])
In	[60]:	x
Out[60]:	[4,	None,	'foo',	7,	8,	(2,	3)]

通过加法将列表串联的计算量较⼤,因为要新建⼀个列表,并且
要复制对象。⽤extend追加元素,尤其是到⼀个⼤列表中,更为
可取。因此:

everything	=	[]
for	chunk	in	list_of_lists:
				everything.extend(chunk)

要⽐串联⽅法快:

everything	=	[]
for	chunk	in	list_of_lists:
				everything	=	everything	+	chunk

排序
你可以⽤sort函数将⼀个列表原地排序(不创建新的对象):

In	[61]:	a	=	[7,	2,	5,	1,	3]
In	[62]:	a.sort()
In	[63]:	a
Out[63]:	[1,	2,	3,	5,	7]

sort有⼀些选项,有时会很好⽤。其中之⼀是⼆级排序key,可
以⽤这个key进⾏排序。例如,我们可以按⻓度对字符串进⾏排
序:

In	[64]:	b	=	['saw',	'small',	'He',	'foxes',	'six']
In	[65]:	b.sort(key=len)
In	[66]:	b
Out[66]:	['He',	'saw',	'six',	'small',	'foxes']

稍后,我们会学习sorted函数,它可以产⽣⼀个排好序的序列副
本。
⼆分搜索和维护已排序的列表
bisect模块⽀持⼆分查找,和向已排序的列表插⼊
值。bisect.bisect可以找到插⼊值后仍保证排序的位
置,bisect.insort是向这个位置插⼊值:

In	[67]:	import	bisect
In	[68]:	c	=	[1,	2,	2,	2,	3,	4,	7]
In	[69]:	bisect.bisect(c,	2)
Out[69]:	4
In	[70]:	bisect.bisect(c,	5)
Out[70]:	6
In	[71]:	bisect.insort(c,	6)
In	[72]:	c
Out[72]:	[1,	2,	2,	2,	3,	4,	6,	7]

注意:bisect模块不会检查列表是否已排好序,进⾏检查的
话会耗费⼤量计算。因此,对未排序的列表使⽤bisect不会
产⽣错误,但结果不⼀定正确。
切⽚
⽤切边可以选取⼤多数序列类型的⼀部分,切⽚的基本形式是在
⽅括号中使⽤start:stop:

In	[73]:	seq	=	[7,	2,	3,	7,	5,	6,	0,	1]
In	[74]:	seq[1:5]
Out[74]:	[2,	3,	7,	5]

切⽚也可以被序列赋值:

In	[75]:	seq[3:4]	=	[6,	3]
In	[76]:	seq
Out[76]:	[7,	2,	3,	6,	3,	5,	6,	0,	1]

切⽚的起始元素是包括的,不包含结束元素。因此,结果中包含
的元素个数是stop - start。
start或stop都可以被省略,省略之后,分别默认序列的开头和
结尾:

In	[77]:	seq[:5]
Out[77]:	[7,	2,	3,	6,	3]
In	[78]:	seq[3:]
Out[78]:	[6,	3,	5,	6,	0,	1]

负数表明从后向前切⽚:

In	[79]:	seq[-4:]
Out[79]:	[5,	6,	0,	1]
In	[80]:	seq[-6:-2]
Out[80]:	[6,	3,	5,	6]

在第⼆个冒号后⾯使⽤step,可以隔⼀个取⼀个元素:

In	[81]:	seq[::2]
Out[81]:	[7,	3,	3,	6,	1]

⼀个聪明的⽅法是使⽤-1,它可以将列表或元组颠倒过来:

In	[82]:	seq[::-1]
Out[82]:	[1,	0,	6,	5,	3,	6,	3,	2,	7]

enumerate函数
迭代⼀个序列时,你可能想跟踪当前项的序号。⼿动的⽅法可能
是下⾯这样:

i	=	0
for	value	in	collection:
			#	do	something	with	value
			i	+=	1

因为这么做很常⻅,Python内建了⼀个enumerate函数,可以返
回(i, value)元组序列:

for	i,	value	in	enumerate(collection):
			#	do	something	with	value

当你索引数据时,使⽤enumerate的⼀个好⽅法是计算序列(唯
⼀的)dict映射到位置的值:

In	[83]:	some_list	=	['foo',	'bar',	'baz']
In	[84]:	mapping	=	{}
In	[85]:	for	i,	v	in	enumerate(some_list):
			....:					mapping[v]	=	i
In	[86]:	mapping
Out[86]:	{'bar':	1,	'baz':	2,	'foo':	0}

sorted函数
sorted函数可以从任意序列的元素返回⼀个新的排好序的列表:

In	[87]:	sorted([7,	1,	2,	6,	0,	3,	2])
Out[87]:	[0,	1,	2,	2,	3,	6,	7]
In	[88]:	sorted('horse	race')
In	[82]:	seq[::-1]
Out[82]:	[1,	0,	6,	5,	3,	6,	3,	2,	7]
Out[88]:	['	',	'a',	'c',	'e',	'e',	'h',	'o',	'r',	'r',	's']

sorted函数可以接受和sort相同的参数。
zip函数
zip可以将多个列表、元组或其它序列成对组合成⼀个元组列
表:

In	[89]:	seq1	=	['foo',	'bar',	'baz']
In	[90]:	seq2	=	['one',	'two',	'three']
In	[91]:	zipped	=	zip(seq1,	seq2)
In	[92]:	list(zipped)
Out[92]:	[('foo',	'one'),	('bar',	'two'),	('baz',	'three')]

zip可以处理任意多的序列,元素的个数取决于最短的序列:

In	[93]:	seq3	=	[False,	True]
In	[94]:	list(zip(seq1,	seq2,	seq3))
Out[94]:	[('foo',	'one',	False),	('bar',	'two',	True)]

zip的常⻅⽤法之⼀是同时迭代多个序列,可能结合enumerate
使⽤:

In	[95]:	for	i,	(a,	b)	in	enumerate(zip(seq1,	seq2)):
			....:					print('{0}:	{1},	{2}'.format(i,	a,	b))
			....:
0:	foo,	one
1:	bar,	two
2:	baz,	three

给出⼀个“被压缩的”序列,zip可以被⽤来解压序列。也可以当
作把⾏的列表转换为列的列表。这个⽅法看起来有点神奇:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值