本篇介绍Tuple和List这两种数组。Dictionary另外单独介绍。
这里仅介绍数组的基本用法。更多高级用法以后逐步讨论。
可以在此位置下载本文中的所有代码:
https://code.csdn.net/snippets/188628/master/ArrayTest.py/raw
可以在此位置下载本文中的所有代码:
https://code.csdn.net/snippets/188628/master/ArrayTest.py/raw
Tuple和List的基本操作
显式地创建一个一维数组
myTuple=('a', 'b', 'c')
或:
myList=['a', 'b', 'c']
myList=['a', 'b', 'c']
注意:
1) 以圆括号创建的数组,是一种名为“Tuple”(元组)的类型。这种类型类似于静态数组,不能动态添加元素,也不能对现有元素进行重新赋值。
2) 以方括号创建的数组,则是一种名为“List”的类型,可以添加、扩充、排序等操作。
基本操作示例
包括:创建数组、打印数组、返回长度# Basic operation of Tuple and List
myTuple = ("foo", 'bar', "b'a'r", 'b\'a\'z', 'b"a"r', "b\"a\"z", "b'a'\"r", 1, None)
print 'Basic operation of tuple:'
print '\tThe tuple is:', myTuple
print '\tLength of the tuple is:', len(myTuple)
myTuple = ('foo', )
print '\tThe single value tuple is:', myTuple, ', it has', len(myTuple), 'element(s).'
myList = [10]
print '\t"myList = [10]" creates a list with', len(myList), 'element(s). The list is:', myList
print ''
注:
- Tuple、List中的元素可以是任意类型,不必,也无法通过语法方式限定它们必须属于同种类型。
- Tuple、List的内容可以直接打印出来。打印时:
- Tuple类型会自动在外围加上圆括号,而List类型则会自动加方括号。
- 各个元素之间用一个逗号和一个空格分隔。
- 字符串类型会自动被加上一对单引号包围。由于单引号和双引号在表示字符串时本质上没有区别,在系统内部都会转换为相通的数据结构,因此无论建立tuple时采用的是单引号还是双引号传入字符串,最终在表示的时候一般都统一使用单引号包围。系统不会“记得”你在创建时是使用的哪种引号。但是:
- 对于字符串中含引号的情况,系统会按照这样的原则打印:1) 若字符串中只有单引号,则外层会用双引号包围,字符串中的单引号前不加转义符;2)若字符串中只有双引号,则外层会用单引号包围,字符串中的双引号前不加转义符;3) 若字符串中既含有单引号也含有双引号,则系统会在外层用单引号包围,字符串内的单引号前加反斜杠“\”转义,字符串内的双引号前不加转义符。
- len函数可以返回一个Tuple和List的实际长度
- 对于只包含一个元素的Tuple,要用形如“('foo', )”这样的方式创建,print时也会用类似的方式print出来(注意print的时候逗号和右括号之间没有空格)。List没有这个要求(尽管也可以使用这种方式,但效果一样)。Tuple要求采用这种方式主要是因为单个括号无法确定到底是赋单个值还是创建Tuple。
- 注意与其它语言不同,“myList = [10]”这样语句不会定义一个含有10个元素的数组,而是定义一个含有一个元素、其内容为数字“10”的List。
二维数组
myTuple=(('a', 'b', 'c'), (1, 2))
print '\tNested Tuple:', myTuple, ', myTuple[1][2]:', myTuple[1][2]
myList=[['a', 'b', 'c'], [2, 1]]
print '\tNested List:', myList , ', myList[2][1]:', myTuple[2][1]
>> Tuple和List获取特定位置上的元素
print 'Get element on specific position:'
myList = ["foo", 1, 'bar', 'baz']
print '\tTesting this list:', myList
print '\tFirst element (myList[0]):', myList[0]
print '\tLast element (myList[-1]):', myList[-1]
print '\tPenultimate element (myList[-2]):', myList[-2]
try:
myList[4]
except IndexError, myErr:
print '\tOut of right boundary (myList[4]):', myErr.message
try:
myList[-5]
except IndexError, myErr:
print '\tOut of right boundary (myList[-5]):', myErr.message
print ''
注:
* 数组下标从0开始
* 可以取倒数元素,下标“-1”为倒数第一个,“-2”为倒数第二个,以此类推
* 正向、反向都不能越界,否则会抛出异常
* 出现异常时需用“except”来捕捉,否则会导致整个程序终止运行。
按一定规则创建包含一系列元素的列表
# Create a list as per certain rule
print 'Create a list as per certain rule:'
print '\tCreate an increasing list using "range(1, 10)":', range(1, 10)
print '\tCreate an increasing list using "range(1, 10, 2)":', range(1, 10, 2)
print '\tCreate a list with certain number of elements which have same value using "[5]*3":', [5]*3
print '\tCreate a list with certain number of elements which have same value using "[5 for i in range(3)]":', \
[5 for i in range(3)]
print ''
* range函数可以创造包含一个递增数列的List,其每个元素都是整数
* range的第一个参数表示递增数列的起始值(含),第二个参数表示递增数列的终止值(不含)
* 递增数列可以从负值开始,但必须为整数。传入小数会报错
* 可以指定递增数列的步长(step)
* 有2种形式可以创建包含一系列等值元素的List
取出数据
切片(取数组中的部分连续的元素)
# Slice
print 'Slice a tuple:'
myTuple = ('foo', 'bar', 'baz', 'qux', 1, None)
print '\tThe tuple is:', myTuple
print '\t* myTuple[0:2] (Slice normally):', myTuple[0:2]
print '\t* myTuple[2:] (Slice to the end):', myTuple[2:]
print '\t* myTuple[:-2] (Slice from the beginning to countdown third):', myTuple[:-2]
print '\t* myTuple[4:2] (Slice with unreasonable indexes):', myTuple[4:2]
print '\t* myTuple[7:-7] (Slice with out-of-boundary indexes):', myTuple[7:1]
print '\t* myTuple[:] (Generate a copy of the List):', myTuple[:]
注:
* Tuple和List都支持切片操作。被切片者为Tuple,则返回Tuple;被切片者为List,则返回List。
* 对于List,切片会返回一个新的List,而不会改变原有的List
* 切片的原则是:从数组下标指定的元素开始(含),到数组下标指定的元素为止(不含)
* 不指定右边界则表示一直取到最后一个元素。不指定左边界表示从头开始。都不指定表示返回一个新的List,其值等于原有的List。
* 支持负值下标(倒数第n位)
* 不合理的切片下标(如“从5到3”),不会导致异常,但会返回空Tuple或List
* 越界的下标也不会导致异常,但只要出现一个越界下标,就会返回空List。
* 既不指定头也不指定尾,则会创建一个新的列表副本,其值与原列表相同。
Tuple、List内的查找
# Search
print 'Search in a tuple:'
myTuple = ('foo', 'bar', 'foo', 10, None)
print '\tThe tuple is:', myTuple
print "\tCheck if there is a 'foo' in the Tuple ('foo' in myTuple):", 'foo' in myTuple
print "\tFind out how many 'foo' in the Tuple (myTuple.count('foo')):", myTuple.count('foo')
print "\tCount non-existence element (myTuple.count('baz')):", myTuple.count('baz')
print '\tFind the position index of first "foo":', myTuple.index('foo')
print "\tSearch from 2nd element to the penultimate one (myTuple.index('foo', 2, -1)):", myTuple.index('foo', 2, -1)
try:
myTuple.index('baz')
except ValueError, myErr:
print "\tFind the position index of non-existence element (myTuple.index('baz')):", myErr.message
print "\tSearch for None value (myTuple.index(None)):", myTuple.index(None)
print ''
注:
* 可以用“in”关键字判断一个对象是否与Tuple或List中的某个元素相等(值相等,非引用相等)。
* count函数可以找到一个对象在整个tuple或list中能找到几个具有相同值的元素
* count一个不存在的元素,会返回0。
* index函数用于找到第一个元素的index(也即该元素的数组下标,从0开始)
* index函数可以指定从数组的哪个位置(含)开始搜索(位置按数组下标记),到哪个位置位置(不含)结束。但找到的数组下标按原数组计。
* index无法做反向查找(即找出是倒数第几个位置),需自行计算。
* index一个不存在的值,会产生异常。
* None值的行为与普通值相同。
在前面介绍循环的时候已经介绍
List的增删改
# Add, Change and Delete operation of List
print 'Add, Change and Delete operation of List:'
向List的末尾追加一个元素(append)
print '\t* Append one element to the end:'
myList = ['foo', 'bar', 10, None]
print '\t\tOriginal List:', myList
testList = myList[:]
testList.append('baz')
print "\t\t> testList.append('baz')", testList
注:
* append函数一次只能添加1个元素
在指定位置上插入一个元素(insert)
# Insert one element at certain position
print '\t* Insert one element at certain position:'
myList = ['foo', 'bar', 10, None]
print '\t\tOriginal List:', myList
testList = myList[:]
testList.insert(2, 'baz')
print "\t\t> testList.insert(2, 'baz')", testList
testList = myList[:]
testList.insert(-1, 'baz')
print "\t\t> testList.insert(-1, 'baz')", testList
testList = myList[:]
testList.insert(5, 'baz')
print "\t\t> testList.insert(5, 'baz')", testList
testList = myList[:]
testList.insert(-6, 'baz')
print "\t\t> testList.insert(-6, 'baz')", testList
注:
* 第一个参数指定插入位置的数组下标,第二个参数指定被插入元素。Python会在该位置之前插入元素。
* 支持负值的数组下标
* 支持越界下标。右边界越界则插入到最后,左边界越界则添加到最开头。
扩充列表(一次添加多个元素到列表末尾)
# Extend List (add multiple elements to the end)
print '\t* Extend List (add multiple elements to the end):'
myList = ['foo', 'bar', 10, None]
print '\t\tOriginal List:', myList
testList = myList[:]
testList.extend(['a', 'b', 'c'])
print "\t\t> testList.extend(['a', 'b', 'c'])", testList
testList = myList[:]
testList.extend(('a', 'b', 'c'))
print "\t\t> testList.extend(('a', 'b', 'c'))", testList
testList = myList[:]
try:
testList.extend(None)
except TypeError, myErr:
print "\t\t> testList.extend(None)", myErr.message
testList = myList[:]
testList.extend('abc')
print "\t\t> testList.extend('abc')", testList
注:
* 不论扩充List还是Tuple,最终都成为List的一部分
* extend方法只能接受一个iterable的对象,传入None会报错。
* 字符串也是iterable的,只是在做为iterable对象时,它的每一个字符都是一个元素
对List中的元素进行更新
# Update a List
print '\t* Update a List:'
myList = ['foo', 'bar', 10, None]
print '\t\tOriginal List:', myList
testList = myList[:]
testList[1] = 'baz'
print "\t\t> testList[1] = 'baz':", testList
testList = myList[:]
testList[0:3] = ['baz', 'qux', 20]
print "\t\t> testList[0:3] = ['baz', 'qux', 20]:", testList
testList = myList[:]
testList[1:3] = ['baz', 'qux', 20]
print "\t\t> testList[1:3] = ['baz', 'qux', 20]:", testList
testList = myList[:]
testList[1:3] = []
print "\t\t> testList[1:3] = ['baz', 'qux', 20]:", testList
testList = myList[:]
testList.insert(1, None)
testList[1:2] = ['baz', 'qux', 20]
print "\t\t> testList.insert(1, None); testList[1:2] = ['baz', 'qux', 20]:", testList
testList = myList[:]
testList.insert(1, None)
testList[1] = ['baz', 'qux', 20]
print "\t\t> testList.insert(1, None); testList[1] = ['baz', 'qux', 20]:", testList
注:
- 直接用数组下标可以对List中的某个元素进行赋值(如:testList[1] = 'baz'),从而达到更新目的。
- 支持一次性对一系列元素重新赋值(如:testList[0:3] = ['baz', 'qux', 20])。起止数组下标原则与切片一致:从左边界(含)开始,到右边界(不含)结束。本例更新0、1、2号位置上的元素。
- 事实上,“被替换”的元素数量,和“替换为”的元素数量可以不一致。例如,testList[1:3] = ['baz', 'qux', 20],将1、2号元素替换为'baz'、'qux'、20三个元素。替换成更多、更少的元素都是允许的。
- 按照这个原理,“testList[1:3] = []”事实上删除了1、2号元素。
- 按照这个原理,“testList.insert(1, None)”,然后再“testList[1:2] = ['baz', 'qux', 20]”事实上可以实现一次性插入多个元素的“insert”操作。
- 注意,“testList[1] = ['baz', 'qux', 20]”会将1号位置的元素变成一个List(二维List),而不是扩充本List。
从List中删除指定位置上的元素
# Delete one or more elements on certain position
print '\t* Delete several elements on certain position:'
myList = ['foo', 'bar', 10, None]
print '\t\tOriginal List:', myList
testList = myList[:]
del testList[1], testList[2]
print '\t\t> del testList[1], testList[2]:', testList
testList = myList[:]
try:
del testList[4]
except IndexError, myErr:
print '\t\t> del testList[4]:', myErr.message
注:
- del命令一次只能删除一个位置上的元素。尽管上面展示了“del myList[1], myList[2]”这种写法,但是它不是同时删除原List中下标为1和2个元素(例子中的'bar'和10),而是先删除下标为1的元素,然后在新List中再删除下标为2的元素(例子中的'bar'和None)。
- 单个元素删除时,越界的下标会产生异常。
从List中删除连续位置上的元素
print '\t* Delete a serials of elements on continuous position:'
myList = ['foo', 'bar', 'baz', 'qux', 10, None]
print '\t\tOriginal List:', myList
testList = myList[:]
del testList[1:4]
print '\t\t> Delete normally (del testList[1:4]):', testList
testList = myList[:]
del testList[2:1]
print '\t\t> Delete with unreasonable indexes (del testList[2:1]):', testList
testList = myList[:]
del testList[2:]
print '\t\t> Delete to the end (del testList[2:]):', testList
testList = myList[:]
del testList[2:-1]
print '\t\t> Delete to the penultimate (del testList[2:-1]):', testList
testList = myList[:]
del testList[6:1]
print '\t\t> Delete out-of-boundary index(es) (del testList[6:1]):', testList
testList = myList[:]
del testList[:]
print '\t\t> Clear up a List (del testList[:]):', testList
注:
删除逻辑与切片完全一致:
* 删除从第一个数字指出的数组下标开始(含),到第二个数字指出的数组下标结束(不含)的所有字符。
* 删除从第一个数字指出的数组下标开始(含),到第二个数字指出的数组下标结束(不含)的所有字符。
* 支持删除到末尾
* 支持负值下标
* 不合理的数组下标组合不会产生异常,但是不删除任何内容
* 删除连续元素时,指定越界的下标,不会产生异常,但只要出现一个越界下标(开始或结束,或两者都越界),都会导致不删除任何内容
* 开头和末尾都不指定,则清空整个List
查找指定值的元素并删除
# Find and remove one element
print '\t* Find and remove one element:'
myList = ['foo', 'bar', 'foo', 10, None]
print '\t\tOriginal List:', myList
testList = myList[:]
testList.remove("foo")
print '\t\t> testList.remove("foo"):', testList
testList = myList[:]
try:
testList.remove("baz")
except ValueError, err:
print '\t\t> testList.remove("baz"):', err.message
testList = myList[:]
target = 'foo'
count = testList.count(target)
while count:
testList.remove(target)
count -= 1
print '\t\t> Remove all', target, ':', testList
注:
删除逻辑和查找类似
* 存在多个同值元素时,只删除第一个
* 删除不存在的值时,会报异常
* 需要删除多个同值元素时,可以自行用循环解决
弹出(pop)
# pop
print '\t* pop:'
myList = ['foo', 'bar', 10, None]
print '\t\tOriginal List:', myList
testList = myList[:]
theElement = testList.pop()
print '\t\t> testList.pop(): the popped element -', theElement, ', the List after popped -', testList
testList = myList[:]
theElement = testList.pop(3)
print '\t\t> testList.pop(3): the popped element -', theElement, ', the List after popped -', testList
testList = myList[:]
theElement = testList.pop(-3)
print '\t\t> testList.pop(-3): the popped element -', theElement, ', the List after popped -', testList
testList = myList[:]
try:
theElement = testList.pop(4)
except IndexError, myErr:
print '\t\t> testList.pop(4):', myErr.message
print ''
注:
* 默认条件下弹出最后一个元素
* 指定元素时,弹出位于指定数组下标上的元素
* 支持负值定位
* 索引越界会抛异常
排序
# Order operation
print 'Order operation'
逆转
# reverse
print '\t* reverse'
myList = ['a', 'c', 'b', 'd']
print '\t\tOriginal List:', myList
myList.reverse()
print '\t\t> myList.reverse():', myList
注:
* 逆转是直接将List按数组下标逆转,而不是按内容排序
按内容排序
# sort
print '\t* sort'
myList = ['a', 'c', 'b', 'D']
print '\t\tOriginal List:', myList
testList = myList[:]
testList.sort()
print '\t\t> testList.sort():', testList
testList = myList[:]
testList.sort(reverse=True)
print '\t\t> testList.sort(reverse=True):', testList
testList = myList[:]
testList.sort(key=str.lower)
print '\t\t> testList.sort(key=str.lower):', testList
print ''
注:
* 正常情况下,按Uniocde顺序排序
* 可以通过“reverse=True”指定倒序
* 可以通过“key=str.lower”指定按小写排序。注意这只决定排序顺序,不会更改List中元素本身的大小写。
* 更多用法以后再讨论
遍历
在前面介绍循环的时候已经介绍
myArr = (10, 11, 12, 13, 14)
for currNum in myArr:
print currNum
注:Tuple和List的遍历方式类似
将字符串数组合并成一个字符串
# Join a String List
print 'Traverse a Tuple'
myArr = ('a', 'b', 'c', 'd', 'e')
print '\tThe Tuple is:', myArr
print '\tJoin:', "".join(myArr)
注:
* 关于数组转字符串的更多内容在字符串部分详细介绍