Python学习笔记-第二章 列表和元组

来源:互联网 发布:我的心时刻牵挂着网络 编辑:程序博客网 时间:2024/05/01 09:36

去了趟厦门,刚回来就开始学习了,真是佩服自己呢。厦门这地儿,去一次就够了,装13圣地,跟我的风格不是很搭,我主要是去吃的,各种海鲜都炒鸡便宜,冲着这个,大概还会再去一趟吧,每家都有团购,真是大众点评的根据地。好了,言归正传,开始学习吧。

第二章 列表和元组

本章开始讲数据结构。数据结构是通过某种方式(如编号)组织在一起的数据元素的集合。可以是数字或者字符,也可能是其它数据结构。

Python中最基本的数据结构是序列(sequence)。序列中每个元素都被分配一个序号(即元素的位置,也称为索引),第一个是0,第二个是1,依此类推。

2.1 序列概览

Python有6种内建的序列,本章重点讨论最常用的两种类型:列表和元组。其它序列类型有:字符串,Unicode字符串,buffer对象和xrange对象。

列表跟元组的区别:列表可以修改,元组不能。大多数情况下,列表可以替代元组(也有例外,当元组作为字典的键,因为键不可修改,所以不能用列表)

需要操作一组数据时,序列很好用。可以用序列表示数据库中一个人的信息,第1个元素是姓名,第2个是年龄,根据上述内容编写一个列表:

edward=['Edward Gumby',42]john=['John Smith',50]database=[edward,john] #结果出现 [['Edward Gumby', 42], ['John Smith', 50]]
Python中还有一个名为容器(container)的数据结构,它是包含其它对象的任意对象,序列和映射是两类主要的容器。容器集合(set)既不是序列也是不是映射。

2.2 通用序列操作

 2.2.1 索引

序列中的都有编号,从0开始递增,可以通过编号来访问这些元素

greeting='hello'greeting[0] #结果显示第一个元素,'h'
使用负数索引时,是从右边开始计数,即最后一个。
greeting[-1] #结果为'o',即最后一个元素。
不能超过元素个数范围

greeting[5] #会报错,因为这个位置不存在元素<pre name="code" class="python">greeting[-6] 同上
如果是调用返回同一个序列,可以直接对返回结果进行索引操作。

fourth=input('year:')[3] #只对输入年份的末位数字感兴趣year:2005fourth #结果显示为'5'


#根据给定的年月日以数字形式打印出日期months=[    'January',    'February',    'March',    'April',    'May',    'June',    'July',    'August',    'September',    'October',    'November',    'December'    ]#以1~30的数字作为结尾的列表endings=['st','nd','rd']+17*['th']\         +['st','nd','rd']+7*['th']\         +['st']year=input('year:')month=input('Month(1-12):')day=input('DAY(1-31):')month_number=int(month)day_number=int(day)#记得要将月份和天数减1,以获得正确的索引month_name=months[month_number-1]ordinal=day+endings[day_number-1]print(month_name+' '+ordinal+','+year)      
2.2.2 分片

分片是访问一定范围内的元素,通过冒号相隔的两个索引来实现。

tag='<a href="http://www.python.org">python web site</a>'tag[9:30] #结果为'http://www.python.org',显示编号9到编号30的元素。tag[32:-4] #运行结果'python web site',显示编号32起至倒数第4个元素。 

分片的操作需要提供两个索引作为边界,第1个索引的元素是包含在分片内的,第2个不包含。

1.优雅的捷径

如果需要访问最后三个,可以有如下操作

numbers=[1,2,3,4,5,6,7,8,9,10]numbers[3:6] #运行结果[4, 5, 6]numbers[-3:-1] #这个结果不是想要的,最后一位元素无法显示,只显示[8, 9]numbers[-3:0] #显示[],如果在分片中最左边的索引比右边的晚出现在序列中,结果就是空的序列。numbers[-3:] #最后一个索引空置就可以出现正确结果了,[8,9,10] numbers[:3] #同样适用于序列开始的元素,结果显示[1,2,3] numbers[:] #复制整个序列。#对http://www.something.com形式的URL进行分割url=input('please enter the URL:')domain=url[11:-4]print("domain name:"+domain)   #提取域名

2.更大的步长。

步长(step lenth)参数通常是隐匿设置的,在普通的分片中,步长是1,分片操作就是按照这个步长逐个遍历序列的元素,然后返回开始和结束点之间的所有元素。

numbers=[1,2,3,4,5,6,7,8,9,10]  #中间运行了其它程序,所以要重新定义一遍numbersnumbers[0:10:1]  #运行结果为[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],定义了步长为1numbers[0:10:2] #运行结果为[1,3,5,7,9]numbers[3:6:3] #运行结果为[4]numbers[::4] #运行结果为[1,5,9]numbers[8:3:-1] #步长可以是负数,即从右向左提取元素,运行结果[9,8,7,6,5]
注意:

  • 步长不能为0
  • 开始点的元素(最左边的)包括在结果之中,结束点的不在
  • 当使用负数为步长时,必须让开始点(开始索引)大于结束点。

2.2.3 序列相加

通过加号可以进行序列的连接操作,两种同一类型的序列才能进行连接。

[1,2,3]+[4,5,6,7] #运行结果[1, 2, 3, 4, 5, 6, 7],跟两个序列元素数量无关'hello,'+'world!'"hello,"+'world!''hello,world!' #这三个都可以正确显示'hello,world!'"hello,"+"1,2,3" #显示'hello,1,2,3',这里的1,2,3是字符[1,2,3]+'hello'#报错,不是同一类型

2.2.4 乘法

用数字X乘以一个序列会生成新的序列,在新序列中,原来的数列会重复X次。

'python'*5   #运行结果'pythonpythonpythonpythonpython'[42]*5   #运行结果[42, 42, 42, 42, 42],这里的[42]是序列而不是数字。 '42'*5  #运行结果'4242424242',这里的‘42’表示字符串[1,2,3]*5   #运行结果 [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
None、空列表和初始化

空列表可以用两个中括号表示[],如果 想要生成一个占用10个元素的空间,却不包含任何内容,就要用到None.

[]*5  #运行结果显示[][None]*5  #运行结果[None, None, None, None, None],这里的None首字母一定要大写,否则报错[]+[] #运行结果[][]+[1,2,3] #运行结果[1,2,3][]+[None] #运行结果[None]

序列(字符串)乘法示例

#以正确的宽度在居中的“盒子”内打印一个句子sentence=input("setence:")screen_width=80text_width=len(sentence)#?为什么box_width=text_width+6left_margin=(screen_width-box_width)//2printprint(' '*left_margin+'+'+'-'*(box_width-6)+ '+')  #<span style="color:#6633FF;">修改了原来的语句才合适,版本差异?原来是-2,导致会长一截</span>print(' '*left_margin+'|'+' '*text_width+'|')print(' '*left_margin+'|'+sentence+'|')print(' '*left_margin+'|'+' '*text_width+'|')print(' '*left_margin+'+'+'-'*(box_width-6)+'+')print
新版本里面应该有改动,导致按照原语句运行无法形成整齐的方格,原因待研究。

2.2.5 成员资格

检查一个值是否在序列中,可以用in运算符。这个运算符是布尔运算符,检查条件是否为真,若为真(布尔值),返回True,假则返回False。

permissions='rw''w' in permissions  #运行结果True 's' in permissions  #运行结果Falseusers=['mlh','foo','bar']input('enter your user name:') in usersenter your user name:mlh #运行结果 Truesubject='$$$ Get rich now!!! $$$' '$$$' in subject #运行结果 True

示例,查看用户输入的用户名和PIN码是否存在于数据库

#检查用户名和PIN码database=[    ['albert','1234'],    ['dilbert','4242'],    ['smith','7524'],    ['jones','9843']    ]username=input('user name:')pin=input('PIN code:')if[username,pin] in database: print ('Access granted')

2.2.6 长度、最小值和最大值

内建函数len,min和max.

Len:返回序列中所包含元素的数量。

min:返回最小的元素

max:返回最大的元素

numbers=[100,34,678]len(numbers)  #序列中共有3个元素,所以返回值为3max(numbers) #返回值678min(numbers) #返回值34max(2,3) #也可以直接使用,3<pre name="code" class="python">min(9,3,2,5) #返回2max[2,3] #报错

2.3 列表:Python的苦力

2.3.1 list函数

字符串不能像列表一样被修改,根据字符串创建列表很有用。

list('hello')  #返回值['h', 'e', 'l', 'l', 'o']list([1,2,3]) #返回值[1, 2, 3],list函数适用于所有类型的序列

2.3.2 基本的列表操作

1.改变列表:元素赋值

x=[1,1,1]x[1]=2x  #返回值[1, 2, 1],x已改变

2.删除元素(del)

names=['Alice','Beth','Cecil','Dee-Dee','Earl']del names[2]names  #返回值['Alice', 'Beth', 'Dee-Dee', 'Earl'],已删除索引标记为2的元素'Cecil'.

3.分片赋值

name=list('Perl')name   #运行结果['P', 'e', 'r', 'l']name[2:]=list('ar')name #运行结果['P', 'e', 'a', 'r'],从第3个元素起变成a,rname[2:]=list('ars')name #运行结果['P', 'e', 'a', 'r','s'] #长度可以不相等numbers=[1,5]numbers[1:1]=[2,3,4] #在第二个位置插入序列numbers    #运行结果[1, 2, 3, 4, 5]numbers[1:4]=[]  #删除元素numbers #返回值[1,5]

2.3.3 列表方法

方法是一个与某些对象有紧密联系的函数。方法的调用形式为:对象.方法(参数)

列表方法append在列表末尾追加新的对象count统计某个元素在列表中出现的次数extend在列表末尾一次性追加另一个序列中的多个值index从列表中找出某个值第一个匹配项的索引位置insert将对象插入到列表中pop移除列表中的一个元素(默认最后一个),并返回该元素的值remove移除列表中某个值的第一个匹配项reverse将列表中的元素反向存放reversed对一个序列进行反向迭代sort在原位置对列表进行排序sorted获取已排序列表副本高级排序按特定方式进行排序


1.append

lst=[1,2,3] #第一个字符为字母l,变量名第一个不能为数字,也不能用list,一旦用了内建函数作为变量名,它就不能被调用了lst.append(4)lst  #返回值[1, 2, 3, 4]

2.count

['to','be','or','not','to','be'].count('to') #'to'在列表中出现的次数,返回2x=[[1,2],1,1,[2,1,[1,2]]]x.count(1) #返回值为2x.count([1,2]) #返回值为1

3.extend

a=[1,2,3]b=[4,5,6]a.extend(b)a  #返回值[1, 2, 3, 4, 5, 6]a=[1,2,3]b.extend(a)b   #返回值[4, 5, 6, 1, 2, 3]
这个用法类似于序列相加,但是序列相加不改变原变量值。如果想要改变变量a的值,需要加上一条a=a+b

也可以用分片赋值,

a=[1,2,3]b=[4,5,6]a[len(a):]=ba            #返回[1, 2, 3, 4, 5, 6],分片赋值真是万能的啊!

4.index

knights=['we','are','the','knights','who','say','ni']knights.index('who') #返回值4knights.index('herring')   #提示错误,herring不在list中

5.insert

numbers=[1,2,3,4,5,6,7]numbers.insert(3,'four')numbers      #返回值[1, 2, 3, 'four', 4, 5, 6, 7],'four'被插入到索引为3的位置上
万能的分片赋值也可以做到。

numbers=[1,2,3,4,5,6,7]numbers[3:3]=['four']nmbers  #可读性不如insert。

6.pop

x=[1,2,3]x.pop()  #这里会先返回值3,默认移除最后一个元素x  #返回值[1, 2],x序列已变。x.pop(0) #返回值1x  #返回值[2]。pop是唯一一个既能修改列表又返回元素值(除了None)的列表方法

用pop方法可以实现一种常见的数据结构——栈。栈的原则是后进先出(LIFO).栈的操作有两个,入栈(push)和出栈(pop),python中没有入栈,可以通过append方法来代替。

x=[1,2,3]x.append(x.pop())x   #返回值[1, 2, 3],入栈的是刚出栈的值,结果还是原来的栈。

7.remove

x=['to','be','or','not','to','be']x.remove('be') #没有返回值,直接修改x  #返回值['to', 'or', 'not', 'to', 'be'],第一个匹配的'be'已经被移除。x.remove('bee')  #报错,'bee'不存在。

8.reverse

x=[1,2,3]x.reverse() x    #返回值[3, 2, 1]

如果需要对一个序列进行反向迭代,可以会用reversed函数

x=[1,2,3]reversed(x)  #返回值是<list_reverseiterator object at 0x00000000035D7B70>,reversed函数返回的是一个迭代器对象list(reversed(x)) #返回值[3, 2, 1],用list函数把它转换成列表。

9.sort

x=[4,6,2,1,7,9]x.sort() x    #返回值[1, 2, 4, 6, 7, 9],按顺序排列
sort是没有返回值的,因此下面的做法是错误的

x=[4,6,2,1,7,9]y=x.sort()print(y)   #返回值None,sort没有返回值x    #返回值[1, 2, 4, 6, 7, 9],被排序了
正确的做法如下

x=[4,6,2,1,7,9]y=x[:] #先对y赋值,把x列表复制进yy.sort()  x  #返回值[4, 6, 2, 1, 7, 9]y   #返回值[1, 2, 4, 6, 7, 9]
复制整个列表不能用简单的赋值,

x=[4,6,2,1,7,9]y=xy.sort()x  #返回值[1, 2, 4, 6, 7, 9]y    #返回值[1, 2, 4, 6, 7, 9]
获取已排序列表副本还可以用sorted函数
x=[4,6,2,1,7,9]y=sorted(x)y   #返回值[1, 2, 4, 6, 7, 9]x   #返回值[4, 6, 2, 1, 7, 9]
sorted的返回值总是返回一个列表

sorted('python')   #返回值['h', 'n', 'o', 'p', 't', 'y']

10.高级排序

python 3.4中cmp函数已被删除。

其它的高级排序方法

x=['aardvark','abalone','acme','add','aerate']x.sort(key=len)  #按长度进行排序,如果有长度一样的单词,会保持原来位置x        #返回值['add', 'acme', 'aerate', 'abalone', 'aardvark']

x=[4,6,2,1,7,9]x.sort(reverse=True)  #这里的True首字母必须大写,否则报错x   #返回值[9, 7, 6, 4, 2, 1]

2.4 元组:不可变序列

元组也是一种序列,不能修改(字符串也是这样)。用逗号分隔一些值就自动创造了元组,元组(大部分时候)通过圆括号括起来的,空元组就是()

1,2,3   #返回值(1, 2, 3)a,b,c   #报错字符必须要用引号'a','b','c'  #返回值('a', 'b', 'c') 42, #返回一个值的元组(42,)42  #返回42,这不是一个元组(42) #返回42,也不是元组,创建元组的关键在逗号,跟括号无关
3*(40+2)  #返回值126,就是数值运算3*(40+2,)  #返回值(42, 42, 42),先进行运算后变成元组3*(40,+2)  #返回值(40, 2, 40, 2, 40, 2)

2.4.1 tuple函数

跟list函数基本一样:以一个序列作为参数并把它转换为元组。

tuple([1,2,3])  #返回值(1, 2, 3)tuple('abc')   #返回值('a', 'b', 'c')tuple((1,2,3))  #返回值(1, 2, 3),本身就是元组,返回自身

2.4.2 基本元组操作

元组只有创建元组和访问元组。

x=1,2,3x[1]  #返回值2,x[0:2]   #返回值(1, 2),元组的分片还是元组 

2.4.3 那么,意义何在

大部分时候,列表可以满足对序列的所有需求。由于以下两个原因,元组无可替代

  1. 元组可以在映射(和集合的成员)中当作键使用,列表不行
  2. 元组作为很多内建函数和方法的返回值存在。














0 0
原创粉丝点击