python学习手册:学习笔记6--Lists and Dictionaries

List

    列表是可改变的容器,并且它的元素可包含任意的数据类型:数字,字符串,甚至列表本身.

Python中列表的属性如下:

Ordered collections of arbitrary objects

    列表的元素可包含任意的数据类型,我们可以把列表当作一个"组"

Accessed by offset

    因为列表本身是序列容器,所以我们可以对它进行索引操作,甚至可以对它进行切片操作.

variable-length, heterogeneous, and arbitrary nestable

    不像字符串,列表可以在空间层面上增加和减少,它们可以包含任何可排序/不可排序的对象,甚至可以包含列表本身.

Of the category "mutable sequence"

    列表是可修改的(跟字符串不同,字符串/数字是不可修改的),任何在字符串上可执行的操作/方法在列表上均可实现:切片,连接,索引等.由于列表是可修改的,所以它支持额外的功能:删除,索引赋值(直接在列表的空间上进行修改)

    以下为列表的通用操作:

Operation
Interpretation
L = []
空列表
L = [123, 'abc', 1.23, {}]
四个元素的列表
L = ['Bob', 40.4, ['dev', 'mgr']]
列表中嵌套列表
L = list('spam')
使用可迭代对象生成列表
L = list(range(-4, 4))

L[i]
列表的索引,索引的索引,切片,长度
L[i][j]

L[i:j]

len(L)

L1 + L2   
列表的连接,重复
L * 3

for x in L: print(x)
可迭代操作
3 in L
成员判断操作
L.append(4)
列表的操作:增长
L.extend([5, 6, 7])

L.insert(i, x)

L.index(X)
列表的操作:查询
L.count(X)

L.sort()
列表的操作:排序,反序
L.reverse()

L.copy()

L.clear()

L.pop(i)
列表的操作:删除
L.remove(X)

del L[i]

del L[i:j]

L[i:j] = []

L[i] = 3
列表的操作:赋值,切片赋值
L[i:j] = [4, 5, 6]

L = [x ** 2 for x in range(5)]

list(map(ord, 'spam'))

Lists in Action

    列表和字符串类似,一样支持"+"和"*"的操作.而如果对字符串和列表进行"+"操作,则需进行强制转换:

>>> len([1, 2, 3])
3
>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
>>> ['Ni!'] * 4
['Ni!', 'Ni!', 'Ni!', 'Ni!']
>>> str([1, 2]) + "34"
'[1, 2]34'
>>> [1, 2] + list("34")
[1, 2, '3', '4']
    列表也可以进行可迭代操作
>>> 3 in [1, 2, 3]
True
>>> for x in [1, 2, 3]:
	print x,

	
1 2 3
    通过for/range/map来进行可迭代操作:
>>> res = [c * 4 for c in 'SPAM']
>>> res
['SSSS', 'PPPP', 'AAAA', 'MMMM']
	等价于:
>>> res = []
>>> for c in 'SPAM':
	res.append(c * 4)

	
>>> res
['SSSS', 'PPPP', 'AAAA', 'MMMM']
    而map可进行元素和方法的关联操作:
>>> list(map(abs, [-1, -2, 0, 1, 2]))
[1, 2, 0, 1, 2]
    列表进行索引,切片和矩形计算(但切片的操作是生成一个新的列表)
>>> L = ['spam', 'Spam', 'SPAM!']
>>> L[2]
'SPAM!'
>>> L[-2]
'Spam'
>>> L[1:]
['Spam', 'SPAM!']
>>> matrix = [(x, y) for x in range(1, 3) for y in range(1, 5)]
>>> matrix
[(1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (2, 3), (2, 4)]
备注:对于复杂的操作,不要使用列表推导式!
    列表和字符串有一个很大的区别在于:列表可更改自身,即它是可修改的.
    我们可以通过索引或者切片来对列表进行修改:
>>> L = ['spam', 'Spam', 'SPAM!']
>>> L[1] = 'eggs'
>>> L
['spam', 'eggs', 'SPAM!']
>>> L[0:2] = ['eat', 'more']
>>> L
['eat', 'more', 'SPAM!']
    基于:数字/字符串是不可改变的,所以我们可以通过id来查看其变化:
>>> L = [1, 2, 3]
>>> id(L), [id(x) for x in L]
(42282376L, [29253736L, 29253712L, 29253688L])
>>> L[1] = 12
>>> id(L), [id(x) for x in L]
(42282376L, [29253736L, 29253472L, 29253688L])
    实际上我们新建了一个对象12,并让指针指向新的对象.
    对于切片的赋值来说,我们实际上执行了两步操作:
1. 删除:我们将切片要赋值的范围内元素删除
2. 插入:在删除的位置上插入新的元素(用C语言实现的Python的列表,应该是链式列表,否则不可以插入空间大小不同的元素)
    所以,我们可以用切片的赋值完成删除,插入,替换等操作:
>>> L = [1, 2, 3]
>>> L[1:2] = [4, 5]
>>> L
[1, 4, 5, 3]
>>> L[1:1] = [6, 7]
>>> L
[1, 6, 7, 4, 5, 3]
>>> L[1:2] = []
>>> L
[1, 7, 4, 5, 3]
>>> L= [1]
>>> L[0:0] = [2, 3, 4]
>>> L
[2, 3, 4, 1]
>>> L[len(L):] = [5, 6, 7]
>>> L
[2, 3, 4, 1, 5, 6, 7]
>>> L.extend([8, 9, 10])
>>> L
[2, 3, 4, 1, 5, 6, 7, 8, 9, 10]
    列表也支持一些方法的操作:
    我们可以使用append方法来在末尾插入一项,通过sort方法来排序:
>>> L = ['eat', 'more', 'SPAM!']
>>> L.append('please')
>>> L
['eat', 'more', 'SPAM!', 'please']
>>> L.sort()
>>> L
['SPAM!', 'eat', 'more', 'please']
    我们可以通过"name=value"的方法来进行排序:
>>> L = ['abc', 'ABD', 'aBe']
>>> L.sort()
>>> L
['ABD', 'aBe', 'abc']
>>> L = ['abc', 'ABD', 'aBe']
>>> L.sort(key=str.lower)
>>> L
['abc', 'ABD', 'aBe']
>>> L = ['abc', 'ABD', 'aBe']
>>> L.sort(key=str.lower, reverse=True)
>>> L
['aBe', 'ABD', 'abc']
    这里要注意一点是:使用类似sort/reverse方法,实际上直接修改了列表.但是如果使用了sorted/reversed等方法,不会修改列表但返回一个新的列表:
>>> L = ['abc', 'ABD', 'aBe']
>>> sorted(L, key=str.lower, reverse=True)
['aBe', 'ABD', 'abc']
>>> L
['abc', 'ABD', 'aBe']
>>> sorted([x.lower() for x in L], reverse=True)
['abe', 'abd', 'abc']
    append和extend方法不同之处在于:append只能扩展单个元素,而extend往往扩展整个列表.我们可以配合append和pop来完成一个堆栈的操作:
>>> L = []
>>> L.append(1)
>>> L.append(2)
>>> L
[1, 2]
>>> L.pop()
2
>>> L
[1]
    还有一些额外的操作如:index(查找其元素的索引),insert(在指定的位置插入元素),remove(删除其元素:第一次出现的元素),count(统计出现元素的次数)
>>> L = ['spam', 'eggs', 'ham']
>>> L.index('eggs')
1
>>> L.insert(1, 'toast')
>>> L
['spam', 'toast', 'eggs', 'ham']
>>> L.remove('eggs')
>>> L
['spam', 'toast', 'ham']
>>> L.pop()
'ham'
>>> L.count('spam')
1
    我们甚至可以使用del来删除元素,或者使用切片赋值来完成:
>>> L = ['spam', 'eggs', 'ham', 'toast']
>>> del L[0]
>>> L
['eggs', 'ham', 'toast']
>>> del L[1:]
>>> L
['eggs']
>>> L = ['Already', 'got', 'one']
>>> L[1:] = []
>>> L
['Already']
>>> L[0] = []
>>> L
[[]]


Dictionaries

    对于Python的字典来说,有如下属性:

Accessed by key, not offset position

    字典有时候也称为关联数组或者哈希表,我们是通过其关键字来进行数据的读取的.

unordered collections of arbitrary objects

    对于字典来说,在空间上并不是顺序存储的,而是通过类似哈希表的方式实现.

variable-length, heterogeneous, and arbitrary nestable

    跟列表类似,字典可以增加也可以减少,它们可以包含任何的数据类型,也支持嵌套.但是对于键值来说,必须是可哈希的,即不可改变,如字符串/数值/集合等.

of the category "mutable mapping"

    字典是可修改的,所以可以通过赋值的方式实现.但是它不支持字符串/列表的绝大部分操作,因为它并不是顺序存储的.

tables of object references(hash tables)

    字典是由哈希表实现的,所以它是通过键值来进行数据的读取.

以下表格是字典的所有操作:

Operation
Interpretation
D = {}
空字典
D = {'name': 'Bob', 'age': 40}
两个元素的字典
E = {'cto': {'name': 'Bob', 'age': 40}}
嵌套的字典
D = dict(name='Bob', age=40)
使用dict函数(元素为可迭代的哈希结构即可)实现的字典:keywords,key/value pairs, zipped key/value pairs, keylists
D = dict([('name', 'Bob'), ('age', 40)])

D = dict(zip(keyslist, valueslist))

D = dict.fromkeys(['name', 'age'])

D['name']
通过键索引
E['cto']['age']

'age' in D   
成员关系操作符
D.keys()
字典所有的键
D.values()
字典所有的值
D.items()
字典所有的键值
D.copy()
浅复制
D.clear()
删除所有的元素
D.update(D2)
合并字典
D.get(key, default)
得到值(如果不存在,则返回默认值)
D.pop(key, default)   
删除字典的值(如果哦不存在,则返回默认值)
D.setdefault(key, default)
设置元素的值(如果元素值存在,则不进行任何的修改,如果不存在,则新建key/default的键值)
D.popitem()
删除键值(具有随机性,因为键值本身存储并不是顺序存储的)
len(D)
字典的长度
D[key] = 42   
字典的赋值
del D[key]   
删除字典的元素(通过值)
list(D.keys())
使用list函数序列化字典的键
D1.keys() & D2.keys()

D.viewkeys(), D.viewvalues()

D = {x: x * 2 for x in range(10)}

Dictionaries in Action

    我们一般使用键值来读取数组:

>>> D = {'spam': 2, 'ham': 1, 'eggs': 3}
>>> D['spam']
2
    使用len函数来读取字典的长度,in来判断成员关系,而我们一般也使用keys()来读取出所有的键来进行操作.

>>> len(D)
3
>>> 'ham' in D
True
>>> list(D.keys())
['eggs', 'ham', 'spam']
    一般情况下我们可以使用赋值的方式给字典新增键/值,但是如果存在如下的情况:如果键存在,则我们不插入;否则,插入.我们就不应该直接赋值,可以使用setdefault方法

>>> D = {'eggs': 3, 'spam': 2, 'ham': 1}
>>> D['ham'] = ['grill', 'bake', 'fry']
>>> D
{'eggs': 3, 'ham': ['grill', 'bake', 'fry'], 'spam': 2}
>>> del D['eggs']
>>> D
{'ham': ['grill', 'bake', 'fry'], 'spam': 2}
>>> D.setdefault('spam', 3)
2
>>> D
{'ham': ['grill', 'bake', 'fry'], 'spam': 2}
>>> D.setdefault('eggs', 3)
3
>>> D
{'eggs': 3, 'ham': ['grill', 'bake', 'fry'], 'spam': 2}
    我们可以使用values()来读取所有的值,而通过items()来获取所有的键值:

>>> D = {'spam': 2, 'ham': 1, 'eggs': 3}
>>> list(D.values())
[3, 1, 2]
>>> list(D.items())
[('eggs', 3), ('ham', 1), ('spam', 2)]
    如果键不存在,则我们读取会出现错误.这时候我们需要使用get函数:

>>> D.get('spam')
2
>>> D.get('toast')	//这里返回None
>>> D.get('toast', 88)
88
    我们可以使用update方法来更新一个字典:

>>> D
{'eggs': 3, 'ham': 1, 'spam': 2}
>>> D2 = {'toast': 4, 'muffin': 5}
>>> D.update(D2)
>>> D
{'toast': 4, 'muffin': 5, 'eggs': 3, 'ham': 1, 'spam': 2}
    字典也可以使用pop函数来删除键/值,或者使用del也不错:

>>> D.pop('muffin')
5
>>> D.pop('muffin')

Traceback (most recent call last):
  File "<pyshell#60>", line 1, in <module>
    D.pop('muffin')
KeyError: 'muffin'
>>> del D['toast']
>>> del D['toast']

Traceback (most recent call last):
  File "<pyshell#62>", line 1, in <module>
    del D['toast']
KeyError: 'toast'
>>> D
{'eggs': 3, 'ham': 1, 'spam': 2}
    所以,在删除字典键值之前,一定要判断键是否存在(通过in实现):

>>> D
{'eggs': 3, 'ham': 1, 'spam': 2}
>>> if 'eggs' in D:
	del D['eggs']

	
>>> D
{'ham': 1, 'spam': 2}
>>> if 'eggs' in D:
	del D['eggs']

	
>>> D
{'ham': 1, 'spam': 2}



使用字典需要注意的地方:
1. 序列的操作通常不适合字典使用:因为字典是哈希结构的,所以类似序列的连接,切片操作均不适合.
2. 赋值操作总会新建一个键/值:对于字典来说,赋值操作会新建一个键/值,所以如果不想要这样,则可以使用setdefault方法,配合in成员关系操作实现.
3. 键并不总是字符串:只要是可哈希的值,均可以作为键,如:数字,字符串,元组.
    对于键不存在的字典,我们读取数据会报错.这时候可以使用三种方法来避免错误:1.使用in操作符来判断键是否存在. 2.使用try...except来捕捉异常.3.通过get方法来读取数据(无键则返回None)

你可能感兴趣的:(python学习手册:学习笔记6--Lists and Dictionaries)