python & flask我是程序员;您好程先生;叫我序员就好了

《Python基础教程》第2章 列表和元组

2015-01-06  本文已影响145人  tangyefei

序列概览

在Python中最基本的数据结构是序列(sequence)。序列共有6种类型,本章只重点讨论两种:列表和元组。该章的大致结构为:

通用序列操作

所有的序列都能进行某些特定的操作,并且Python还带有计算长度、寻找最大和最小元素等功能的内建方法。

索引

序列总所有的元素都是带编号的,0表示从第一位开始,-1表示从最后一位开始。字符串就是一个由字符组成序列:

>>> greeting = "Hello"
>>> greeting[0]
'H'
>>> "Hello"[-1]
'o'   

接下来该书实例给了一个小程序。当做练习个人简单把要求抽象一下,如果你也是同我一样刚刚入门Python可以试着自己编编看:

要求用户输入年、月(1-12)、日(1-31),然后按照形如:September 12th,2014 的格式输出构建的字符串。

如下是自己构建的一段代码以及相应的输入输出结果:

year = raw_input("Year:")
month = raw_input("Month(1-12):")
day = raw_input("Day(1-31):")

monthes = [
    "January",
    "February",
    "March",
    "April",
    "Ma",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
]
#此处个人对英文位数的后缀表示法理解有偏差
days = ['st', 'rd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th'];

print monthes[int(month) - 1] + ' ' + day + days[int(day) - 1] + ',' + year

执行即可看到如下结果:

$ python sequencePractise.py
Year:2015
Month(1-12):1
Day(1-31):5
January 5th,2015

相比之教程上的代码,有些东西是可以改进的
(1)在英文表达习惯中第1-3的后缀是st、nd、rd, 其余则是th。比如:1st、12nd、23rd、15th。
(2)因为还没有学习分支(if else)所以这里用了一个长度为31的元组来用于后缀的使用。在Python中可以使用数组的拼接(跟Java和JavaScript比起来是新鲜的东西),如下:
days = ['st', 'nd', 'rd'] + 7*['th']+['st', 'nd', 'rd'] + 7*['th']+['st', 'nd', 'rd'] + 7*['th']+['st'] + ['st']

分片

分片简而言之就是指定开始索引、结束索引,然后得到一个子序列的操作。因为Python提供的分片操作非常灵活,一个一个介绍未必繁琐,下面列出书中的例子。可以先看输入猜测输出,再实际操作或者看结果来印证:

> numbers = [1,2,3,4,5,6,7,8,9,10]
> numbers[3:6]   
[4, 5, 6] #注意索引为6的数字没有算在内

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

> numbers[-3:0]   
[] #第二个索引位置在第一个索引位置的前面

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

> numbers[:-3] 
[1,2,3,4,5,6,7]

> numbers[:] 
[1,2,3,4,5,6,7,8,9,10] # 结果相当于复制整个序列

> numbers[0:10:2] 
[1, 3, 5, 7, 9]#第三个参数为步长

> numbers[8:3:-1]  
[9, 8, 7, 6, 5]#步长可以为负数,索引大小也要反过来

> numbers[0:10:-2] 
[]

> numbers[8::-2] 
[9, 7, 5, 3, 1]
> numbers[5::-2] 
[6, 4, 2]
> numbers[:5:-2] 
[10,8]
#如上三个例子可以知道当其中一个索引没传值的时候,会根据步长的正负来设置默认的索引值。
并且注意:索引所指向的值不包含在切片结果中。
序列相加
> [1,2,3]+[4,5,6]  
[1, 2, 3, 4, 5, 6]

> "Hello" + " World" 
"Hello World"

> "Hello" + [1,2,3]  
#结果:error,序列是分类型的,只有同类型的序列才能相加
乘法

数字乘以序列会生成一个新的序列,新序列中原先的内容被重复若干次。

> "Python"*3
"PythonPythonPython"

> [42]*5
[42, 42, 42, 42, 42]
是否包含成员

使用in运算符可以检测一个知道是否包含在序列中:
> permission = 'rw'
> 'w' in permission
True

> users = ['admin', 'root']
> raw_input('Enter your name:') in users
Enter your name:admin
True
长度、最小值和最大值
>>> numbers = [823, 428, 105]
>>> len(numbers)
3
>>> max(numbers)
823
>>> min(numbers)
105
>>> max(6,3,9,5)
9 #max、min也可以传入多个参数来获取最大最小值

列表

列表是可变的,并且有很多有用的、专门的方法。

list函数

函数不只是能对字符串使用,对所有类型的序列都能用。如下为根据字符串创建列表的例子:

>>> list("Hello")
['H', 'e', 'l', 'l', 'o']
基本的列表操作

列表是序列的一种,那么所有序列的操作都是用于列表,不同在于列表可以改变,该部分介绍改变列表的方法:元素赋值、元素删除、分片赋值、列表方法(并非所有列表方法都能改变列表)。

>>> x=[1,1,1]
>>> x[1]=2
>>> x
[1, 2, 1]
>>> names = ['John', 'Swift', 'Skylar']
>>> del names[1]
>>> names
['John', 'Skylar']
>>> name = list('Perl')
>>> name[2:] = list('ar')
>>> name
['P', 'e', 'a', 'r']

>>> name = list('Perl')
>>> name[1:] = list('ython')
>>> name
['P', 'y', 't', 'h', 'o', 'n']
#在这里我们使用了不等长的列表进行切片替换。

>>> numbers = [1,5]
>>> numbers[1:1] = [2,3,4]
>>> numbers
[1, 2, 3, 4, 5]
#这里起到了插入新元素的作用

>>> numbers = [1,2,3,4,5]
>>> numbers[1:4]=[]
>>> numbers
[1, 5]
#这里起到了删除元素的作用。结合利用步长、负数可以有更多花样。
列表方法
> [1,2,3].append(4)
[1,2,3,4]
> ['to', 'be', 'or', 'not', 'to', 'be'].count('to')
2
a = [1, 2, 3]
b = [4, 5, 6]
a.extend(b)
a
[1, 2, 3, 4, 5, 6]
#可以看到a发生了改变,这是与直接使用a+b不同的。

当然该方法可以有别的如下两种替代办法:

> a = a + b
> a[len(a):] =  b
['to', 'be', 'or', 'not', 'to', 'be'].index('or')
2
>>> numbers = [1, 2, 3, 4]
>>> numbers.insert(2, 'three')
>>> numbers
[1, 2, 'three', 3, 4]

如上操作也等价于切片操作:

>>> numbers[3:3]=['three']
>>> numbers = [1,2,3]
>>> numbers.pop()
3
>>> numbers
[1, 2]

实现栈这种结构就可以通过结合使用(append和pop这两个方法来实现)。实现队列的话,则可以通过给pop和append添加为0的下标作为第一个参数。

>>> x = ['to', 'be', 'or', 'not', 'to', 'be']
>>> x.remove('be')
>>> x
['to', 'or', 'not', 'to', 'be']

如上移除的为第一个匹配项。

>>> x = [1, 2, 3]
>>> x.reverse()
>>> x
[3, 2, 1]
>>> x = [4,7,2,1,7,9]
>>> x.sort()
>>> x
[1, 2, 4, 7, 7, 9]

该书在介绍如上绝大多数方法中都提到了(1)是否返回值(2)是否改变列表本身。个人觉得缺乏使用经验之前想要记忆住这些东西没有实际意义,真正使用的时候通过命令行简单测验就可以知道。

如果希望按照自己定义的规则对列表进行排序,需要传递compare方法给sort,sort默认使用的是内建函数cmp(大于返回1,小于返回-1,等于返回0)。此处暂不详细叙述,原理跟Java应该是一样的。

>cmp(94, 39)
1

元组:不可变序列

如下列出了元组的常用表示法:

>1, 2, 3
(1, 2, 3)
>(1, 2, 3)
(1, 2, 3)
>()
()
> 42,
(42,)
> (42,) * 3
(42, 42, 42)
tuple函数

tuple是将序列转化为元组的函数,和列表总的list类似:

>>> tuple([1,2,3])
(1, 2, 3)
>>> tuple('hello')
('h', 'e', 'l', 'l', 'o')
元组基本操作

创建、访问、切片操作都和列表类似。

元组存在的意义

一般来说,列表能够满足绝大多数的需要。书中所提及元组存在的意义,现在还体会不深,暂且不管。

上一篇下一篇

猜你喜欢

热点阅读