2 列表和元组(1)

目录

2.1 序列概览

2.2 通用序列操作

2.2.1 索引

         代码清单2-1 索引示例

 2.2.2 分片

         代码清单2-2 分片示例

2.2.3 序列相加

2.2.4 乘法

         代码清单2-3 序列(字符串)乘法示例

2.2.5 成员资格

         代码清单2-4 序列成员资格示例

2.2.6 长度、最小值、最大值


数据结构:数据结构是通过某种方式(例如对元素进行编号)组织在一起的数据元素的集合,这些数据元素可以使数字或者字符,甚至可以是其他数据结构。Python中,最基本的数据结构是序列(sequence)。序列中每个元素被分配一个序号---即元素的位置,也称为索引。第一个索引是0,第二个是1,以此类推。(序列中最后一个是-1,倒数第二个是-2)

2.1 序列概览

Python中包含6种内建的序列,这章主要是:列表和元组,其他对应序列类型有字符串、Unicode字符串、buffer对象和xrange对象

列表和元组主要区别是:列表可以修改,而元组不能

可用序列表示数据库中一个人的信息---第一个元素表示姓名第二个元素表示年龄。(列表的各个内容采用逗号分隔,写在方括号中)

>>> edward = ['Edward Gumby', 42]

 同时序列也可以包含其他序列,如:构建一个人员信息的列表

>>> edward = ['Edward Gumby', 42]
>>> john = ['John Smith', 50]
>>> database = [edward,john]
>>> database
[['Edward Gumby', 42], ['John Smith', 50]]

Ps:python中还有一种名为容器(container)的数据结构,容器基本上是包含其他对象的任意对象。序列(如列表和元组)和映射(如字典)是两类主要的容器。序列中每个元素都有自己的编号,而映射中的每个元素则有一个名字(也称为键)。至于既不是序列也不是映射的容器类型,如集合(set)就是一种。

2.2 通用序列操作

所有序列类型都可以进行某些特定的操作。这些操作包括:索引(indexing)、分片(slicing)、加(adding)、乘(multiplying)以及检查某个元素是否属于序列的成员(成员资格)。除此之外,python还有计算序列长度、找出最大元素和最小元素的内建函数。

Ps:迭代(iteration),依次对序列中的每个元素重复执行某些操作。

2.2.1 索引

序列中所有元素都是有编号的---从0开始递增,可以通过编号分别访问元素

>>> greeting = 'hello'
>>> greeting[0]
'h'
>>> greeting[-1]
'o'

Ps:字符串就是有字符组成的序列

使用负数索引,python会从右边,也就是最后一个元素开始计数,最后一个元素的位置编号是-1

如果一个函数调用返回一个序列,那么可以直接对返回结果进行索引操作。列入架设置对用户输入年份的第四个数字感兴趣。

>>> fourth = raw_input('Year: ')[3]
Year: 2005
>>> fourth
5

代码清单2-1 索引示例

[root@localhost python]# vim getYear.py
#!/usr/bin/python2
#coding=utf-8     #否则若python默认编码是ASCII,中文就会报错

#根据给定的年月日以数字形式打印出日期
months = ['January', 'February', 'March', 'April', 'May', \
          'June', 'July', 'August', 'September', 'October', 'November', 'December']

#以1~31的数字作为结尾的列表
# 拼接字符串['st','nd','rd'] +17个th+['st','nd','rd'] +7个th+['st']   一共31个 
endings = ['st','nd','rd'] + 17*['th']\
        + ['st','nd','rd'] + 7*['th']\
        + ['st']          
year = raw_input("Year: ")
month = raw_input("Month (1-12): ")
day = raw_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

[root@localhost python]# chmod a+x getYear.py
[root@localhost python]# ./getYear.py
Year: 1974
Month (1-12): 8
Day (1-31): 16
August 16th, 1974

自己打印一下可以看到>>> print endings

['st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'st']

Ps:1:first 2:second 3:third 4:fourth 5:fifth 6:sixth 7:seventh 8:eighth 9:ninth 10:tenth 11:eleventh 12:twelfth 13:thirteenth 14:fourteenth 15:fifteenth 16:sixteenth 17:seventeenth 18:eighteenth 19:ninteenth 20:twentieth21:twentyfirst 22:twenty-second 23:twenty-third24:twenty-fourth 25:twenty-fifth 26:twenty-sixth 27;twenty-seventh 28:twenty-eighth 29:twenty-ninth 30:thirtieth 31:thirty-first           也就是['st','nd','rd'] +17个th+['st','nd','rd'] +7个th+['st']   一共31个

 2.2.2 分片

与使用索引来访问单个元素类似,可以使用分片操作来访问一定范围内的元素。分片通过冒号隔开的两个索引来实现

>>> tag = '<a href="http://www.python.org">Python web site</a>'
>>> tag[9:30]
'http://www.python.org'
>>> tag[32:-4]
'Python web site'

分片操作对于提取序列比较有用,而且编号在这里也很重要,第一个索引是要提取第一个元素的编号,而最后的索引则是分片之后剩余部分的第1个元素的编号

>>> numbers = [1,2,3,4,5,6,7,8,9,10]
>>> numbers[3:6]
[4, 5, 6]
>>> numbers[0:1]
[1]

分片:提供两个索引作为边界,第一个索引的元素是包含在分片内的,而第二个则不包含在分片内,如:numbers[3:6]就是numbers[3],numbers[4],numbers[5]

(1)优雅的捷径

>>> numbers = [1,2,3,4,5,6,7,8,9,10]

Numbers有10个元素,索引10就是指向第11个元素,这个元素并不存在,确是在最后一个元素之后。

Ps:最后一个元素之后:为了让分片部分包括列表的最后一个元素,必须提供最后一个元素的下一个元素所对应的索引作为边界

 也就是numbers[7:10]的话,因为[7:10]中numbers[10]是不包含在分片内的。

假设需要后三位,怎么做

>>> numbers[-3:-1]   #并没有把numbers[-1]打印出来,试试
[8, 9]
>>> numbers[-3:0]    #显示的是空
[]

这个例子中分片最左边的索引比它右边的晚出现在序列中(在这个例子中倒数第3个比第1个晚出现),结果就是一个空的序列。 

Ps:我理解的是numbers[0]在numbers[-3]前,如[-3,-5]就不合理,一样打印空[]

如果分片所得的部分包括序列结尾的元素,那么只需要置空最后一个索引即可

>>> numbers[-3:]
[8, 9, 10]

同样适用于开始的元素

>>> numbers[:3]
[1, 2, 3]

如果需要复制整个序列,则可以将两个索引都置空

>>> numbers[:]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

代码清单2-2 分片示例

[root@loongbari23 python]# vim slicingtest.py
#!/usr/bin/python2
#coding=utf-8
#对http://www.something.com形式的URL进行分割
url=raw_input('Please enter the URL: ')
domain=url[11:-4]
print "Domain name: "+ domain

[root@localhost python]# chmod a+x slicingtest.py 
[root@localhost python]# ./slicingtest.py
Please enter the URL: http:www.python.org
Domain name: python

(2)更大的步长

进行分片的时候,分片的开始和结束点都需要进行指定,而另一个参数----步长(step length)通常都是隐式设置的,默认是1,分片操作就是按照这个步长逐个遍历序列的元素,然后返回开始和结束点之间的所有元素

>>> numbers = [1,2,3,4,5,6,7,8,9,10]
>>> numbers[0:10:1]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

这个例子中,步长为1,则逐个遍历

>>> numbers[0:10:2]
[1, 3, 5, 7, 9]
>>> numbers[3:6:3]
[4]

步长为2,大于1,则会每2个元素提取一个(跳过一个元素,每隔一个元素打印一次);步长为3,则是在numbers[3:6]中每3个元素提取一个,也就是4 5 6中提取4之后下一个应该是7,此处只有4

以下采用捷径每4个元素中第一个提取出来

>>> numbers = [1,2,3,4,5,6,7,8,9,10]
>>> numbers[::4]
[1, 5, 9]

步长不能为0,但可以是负数,分片从右到左提取元素

>>> numbers[8:3:-1]   #8>3,从右到左n[8]比n[3]先出现,必须先出现的写前面
[9, 8, 7, 6, 5]
>>> numbers[10:0:-2]
[10, 8, 6, 4, 2]
>>> numbers[0:10:-2]
[]
>>> numbers[::-2]
[10, 8, 6, 4, 2]
>>> numbers[5::-2]
[6, 4, 2]
>>> numbers[:5:-2]
[10, 8]

Ps:开始点的元素(最左边元素 )包括在结果中,而结束点的元素(最右边的元素)不在分片之内,当使用一个负数作为步长时,必须让开始点(开始索引)大于结束点

对于正数步长,python会从序列的头部开始向右提取元素,直到最后一个元素,而对于负数步长,则是从序列的尾部开始向左提取元素,直到第一个元素

2.2.3 序列相加

通过使用加运算符可进行序列的连接操作

>>> 'hello, ' + 'world!'
'hello, world!'
>>> [1,2,3] + 'world!'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list

列表和字符串无法连接,尽管他们都是序列;只有两种相同类型的序列才能进行连接

2.2.4 乘法

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

>>> 'python'*5
'pythonpythonpythonpythonpython'
>>> [42]*10
[42, 42, 42, 42, 42, 42, 42, 42, 42, 42]

None、空列表和初始化

空列表用简单的中括号来表示

>>> [None]*10
[None, None, None, None, None, None, None, None, None, None]

代码清单2-3 序列(字符串)乘法示例

会在屏幕打印一个有字符组成的“盒子”,而这个“盒子”在屏幕上居中而且能根据用户输入的句子自动调整大小。

只使用了基本的算法:计算出有多少空格、破折号等字符,然后将他们放到合适的位置

#!/usr/bin/python2
#coding=utf-8
#以正确的宽度在剧中的“盒子”内打印一个句子
#注意,整数除法运算符(//)只能用在python2.2及以后的版本,在之前版本只能用普通除法(/)
sentence = raw_input("Sentence: ")
screen_width = 80
text_width = len(sentence)     #He's a very naughty boy!共24字节
box_width = text_width + 6    #box_width=24+6=30
left_margin = (screen_width - box_width) // 2       #left_margin=(80-30)//2=25

print "="*100
print ' ' * left_margin + '+' + '-' * (box_width-2) + '+'      #25个空格,+号,28个-号,+号    
print ' ' * (left_margin + 4) + '| ' + ' ' * text_width + ' |'    #29个空格,”| “,24个空格,” |”
print ' ' * (left_margin + 4) + '| ' +       sentence   + ' |'        #29空格,”| ”句子,” |”
print ' ' * (left_margin + 4) + '| ' + ' ' * text_width + ' |'        #29空格,”| ”,24空格,” |”
print ' ' * left_margin + '+' + '-' * (box_width-2) + '+'
print "="*100

 打印如下图所示

2.2.5 成员资格

检查值是否在序列中,可以使用in运算符

>>> permissions = 'rw'
>>> 'w' in permissions
True
>>> 'x' in permissions
False

>>> users = ['mlh','foo','bar']
>>> input('Enter your user name: ') in users
Enter your user name: mlh
True

>>> subject = '$$$ Get rich now!!! $$$'
>>> '$$$' in subject
True

 代码清单2-4 序列成员资格示例

[root@localhost python]# vim checkmember.py

#!/usr/bin/python2.7  
#coding=utf-8
#检查用户名和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')

采用IDLE运行结果(Ps:linux中注意,如果第一行不是#!/usr/bin/python2.7,那执行的时候就要使用# python checkmember.py形式)

而且python2此处不能用input要用raw_input,否则输入albert的时候会报错NameError: name 'albert' is not defined;如果python2尽可能使用raw_input;具体可以参考 (input会认为这个已经是合法的,raw_input则作为原始数据,再存放到字符串中) 

2.2.6 长度、最小值、最大值

>>> numbers = [100, 34, 678]
>>> len(numbers)
3
>>> max(numbers)
678
>>> min(numbers)
34
>>> max(2,3)
3
>>> min(9,3,2,5)
2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值