Python复习笔记——序列

Python复习笔记——Python序列

  • Python中常用的序列结构有列表、元组、字符串,字典、集合以及range、map、enumerate、zip、filter等对象也支持很多类似的操作。

列表

  • 列表是Python中内置有序、可变序列,列表的所有元素放在一对中括号[]中,并使用逗号分隔开
  • 当列表元素增加或删除时,列表对象自动进行扩展或收缩内存,保证元素之间没有缝隙
  • 在Python中,一个列表中的数据类型可以各不相同,可以同时分别为整数、实数、字符串等基本类型,甚至是列表、元组、字典、集合以及其他自定义类型的对象。
方法说明
lst.append(x)将元素x添加至列表lst尾部
lst.extend(L)将可迭代对象L中所有元素添加至列表lst尾部
lst.insert(index, x)在列表lst指定位置index处添加元素x,该位置后面的所有元素后移一个位置
lst.remove(x)在列表lst中删除首次出现的指定元素,该元素之后的所有元素前移一个位置
lst.pop([index])删除并返回列表lst中下标为index(默认为-1)的元素
lst.clear()删除列表lst中所有元素,但保留列表对象
lst.index(x)返回列表lst中第一个值为x的元素的下标,若不存在值为x的元素则抛出异常
lst.count(x)返回指定元素x在列表lst中的出现次数
lst.reverse()对列表lst所有元素进行逆序
lst.sort(key=None, reverse=False)对列表lst中的元素进行排序,key用来指定排序依据,reverse决定升序(False)还是降序(True)
lst.copy()返回列表lst的浅复制

列表的创建

  • 使用“=”直接将一个列表赋值给变量即可创建列表对象
>>> a_list = ['a', 'b', 'mpilgrim', 'z', 'example']
>>> a_list = []                            #创建空列表
  • 也可以使用list()函数将元组、range对象、字符串或其他类型的可迭代对象类型的数据转换为列表。
>>> a_list = list((3,5,7,9,11))
>>> a_list
[3, 5, 7, 9, 11]
>>> list(range(1,10,2))
[1, 3, 5, 7, 9]
>>> list('hello world')
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>> x = list()                            #创建空列表

列表删除

  • 当不再使用时,使用del命令删除整个列表
>>> del a_list

列表元素的增加

"+"运算符
  • 可以使用“+”运算符将元素添加到列表中。
>>> aList = [3,4,5]
>>> aList = aList + [7]
>>> aList
[3, 4, 5, 7]

严格意义上来讲,这并不是真的为列表添加元素,而是创建了一个新列表,并将原列表中的元素和新元素依次复制到新列表的内存空间。由于涉及大量元素的复制,该操作速度较慢,在涉及大量元素添加时不建议使用该方法。

使用列表对象的append()方法
  • 原地修改列表,是真正意义上的在列表尾部添加元素,速度较快。
>>> aList.append(9)
>>> aList
[3, 4, 5, 7, 9]
  • Python采用的是基于值的自动内存管理方式,当为对象修改值时,并不是真的直接修改变量的值,而是使变量指向新的值,这对于Python所有类型的变量都是一样的
>>> a = [1,2,3]
>>> id(a)                        #返回对象的内存地址
20230752
>>> a = [1,2]
>>> id(a)
20338208
  • 列表中包含的是元素值的引用,而不是直接包含元素值
  • 如果是直接修改序列变量的值,则与Python普通变量的情况是一样的
  • 如果是通过下标来修改序列中元素的值或通过可变序列对象自身提供的方法来增加和删除元素时,序列对象在内存中的起始地址是不变的,仅仅是被改变值的元素地址发生变化,也就是所谓的“原地操作”
>>> a = [1, 2, 3]
>>> id(a)
2389572193096
>>> a.append(4)
>>> a.remove(3)
>>> a[0] = 5
>>> a
[5, 2, 4]
>>> id(a)
2389572193096
使用列表对象的extend()方法
  • 通过extend()方法来增加列表元素也不改变其内存首地址,属于原地操作
>>> a.extend([7,8,9])
>>> a
[5, 2, 4, 7, 8, 9]
>>> aList.extend([11,13])
>>> aList
[3, 4, 5, 7, 9, 11, 13]
>>> aList.extend((15,17))
>>> aList
[3, 4, 5, 7, 9, 11, 13, 15, 17]
  • 运算符+=类似于列表的extend()方法
使用列表对象的insert()
>>> aList.insert(3, 6)                #在下标为3的位置插入元素6
>>> aList
[3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
  • 列表的insert()可以在列表的任意位置插入元素,但由于列表的自动内存管理功能,insert()方法会引起插入,这会影响处理速度
  • 类似的还有后面介绍的remove()位置之后所有元素的移动方法以及使用pop()方法弹出列表非尾部元素和使用del命令删除列表非尾部元素的情况
使用乘法
>>> aList = [3,5,7]
>>> aList * 3
[3, 5, 7, 3, 5, 7, 3, 5, 7]
  • 当使用*运算符将包含列表的列表重复并创建新列表时,并不是复制子列表值,而是复制已有元素的引用。因此,当修改其中一个值时,相应的引用也会被修改
>>> x = [[None] * 2] * 3
>>> x
[[None, None], [None, None], [None, None]]
>>> x[0][0] = 5
>>> x
[[5, None], [5, None], [5, None]]

列表元素的删除

使用del
>>> a_list = [3,5,7,9,11]
>>> del a_list[1]
>>> a_list
[3, 7, 9, 11]
使用列表的pop()方法
  • 删除并返回指定位置(默认为最后一个)上的元素,如果给定的索引超出了列表的范围则抛出异常
>>> a_list = list((3,5,7,9,11))
>>> a_list.pop()
11
>>> a_list
[3, 5, 7, 9]
>>> a_list.pop(1)
5
>>> a_list
[3, 7, 9]
使用列表的remove()方法
  • 使用列表对象的remove()方法删除首次出现的指定元素,如果列表中不存在要删除的元素,则抛出异常
>>> a_list = [3,5,7,9,7,11]
>>> a_list.remove(7)
>>> a_list
[3, 5, 9, 7, 11]
  • 在删除列表元素时,Python会自动对列表内存进行收缩并移动列表元素以保证所有元素之间没有空隙,增加列表元素时也会自动扩展内存并对元素进行移动以保证元素之间没有空隙。每当插入或删除一个元素之后,该元素位置后面所有元素的索引就都改变了

列表元素的访问与计数

下标直接访问

直接访问列表元素,如果指定下标不存在,则抛出异常

>>> aList[3]
6
>>> aList[3] = 5.5
>>> aList
[3, 4, 5, 5.5, 7, 9, 11, 13, 15, 17]
>>> aList[15]
Traceback (most recent call last):
  File "<pyshell#34>", line 1, in <module>
    aList[15]
IndexError: list index out of range
使用列表对象的index()方法访问
  • 使用列表对象的index()方法获取指定元素首次出现的下标,若列表对象中不存在指定元素,则抛出异常。
>>> aList
[3, 4, 5, 5.5, 7, 9, 11, 13, 15, 17]
>>> aList.index(7)
4
>>> aList.index(100)
Traceback (most recent call last):
  File "<pyshell#36>", line 1, in <module>
    aList.index(100)
ValueError: 100 is not in list
使用列表对象的count()方法统计出现次数
>>> aList
[3, 4, 5, 5.5, 7, 9, 11, 13, 15, 17]
>>> aList.count(7)
1
>>> aList.count(0)
0
>>> aList.count(8)
0

成员资格判断

使用in关键字来判断一个值是否存在于列表中,返回结果为“True”或“False”

>>> aList
[3, 4, 5, 5.5, 7, 9, 11, 13, 15, 17]
>>> 3 in aList
True
>>> 18 in aList
False
>>> bList = [[1], [2], [3]]
>>> 3 in bList
False

切片操作

  • 切片适用于列表、元组、字符串、range对象等类型,但作用于列表时功能最强大。可以使用切片来截取列表中的任何部分,得到一个新列表,也可以通过切片来修改和删除列表中部分元素,甚至可以通过切片操作为列表对象增加元素

  • 切片使用2个冒号分隔的3个数字来完成:

    第一个数字表示切片开始位置(默认为0)。

    第二个数字表示切片截止(但不包含)位置(默认为列表长度)。

    第三个数字表示切片的步长(默认为1),当步长省略时可以顺便省略最后一个冒号

  • 切片操作不会因为下标越界而抛出异常,而是简单地在列表尾部截断或者返回一个空列表,代码具有更强的健壮性

>>> aList = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> aList[::]                            #返回包含所有元素的新列表
[3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> aList[::-1]                          #逆序的所有元素
[17, 15, 13, 11, 9, 7, 6, 5, 4, 3]
>>> aList[::2]                           #偶数位置,隔一个取一个
[3, 5, 7, 11, 15]
>>> aList[1::2]                          #奇数位置,隔一个取一个
[4, 6, 9, 13, 17]
>>> aList[3::]                           #从下标3开始的所有元素
[6, 7, 9, 11, 13, 15, 17]
>>> aList[3:6]                           #下标在[3, 6)之间的所有元素
[6, 7, 9]
>>> aList[0:100:1]                       #前100个元素,自动截断
[3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> aList[100:]                          #下标100之后的所有元素,自动截断
[]
>>> aList[100]                           #直接使用下标访问会发生越界
IndexError: list index out of range
  • 使用切片操作修改列表
>>> aList = [3, 5, 7]
>>> aList[len(aList):] = [9]      #在尾部追加元素
>>> aList
[3, 5, 7, 9]
>>> aList[:3] = [1, 2, 3]         #替换前3个元素
>>> aList
[1, 2, 3, 9]
>>> aList[:3] = []                #删除前3个元素
>>> aList
[9]
>>> aList = list(range(10))
>>> aList
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> aList[::2] = [0]*5            #替换偶数位置上的元素
>>> aList
[0, 1, 0, 3, 0, 5, 0, 7, 0, 9]
>>> aList[::2] = [0]*3            #切片不连续,两侧元素个数必须一样多
ValueError: attempt to assign sequence of size 3 to extended slice of size 5
  • 使用del与切片结合来删除列表元素
>>> aList = [3,5,7,9,11]
>>> del aList[:3]                          #删除前3个元素
>>> aList
[9, 11]

>>> aList = [3,5,7,9,11]
>>> del aList[::2]                         #删除偶数位置上的元素
>>> aList
[5, 9]
  • **切片返回的是浅复制。**所谓浅复制,是指生成一个新的列表,并且把原列表中所选元素的引用都复制到新列表中。如果原列表中只包含整数、实数、复数等基本类型或元组、字符串这样的不可变类型的数据,一般是没有问题的
>>> aList = [3, 5, 7]
>>> bList = aList[::]                 #切片,浅复制
>>> aList == bList                    #两个列表的元素完全一样
True
>>> aList is bList                    #但不是同一个对象
False
>>> id(aList) == id(bList)            #内存地址不一样
False
>>> bList[1] = 8                      #修改其中一个不会影响另一个
>>> bList
[3, 8, 7]
>>> aList
[3, 5, 7]
  • 如果原列表中包含列表之类的可变数据类型,由于浅复制时只是把子列表的引用复制到新列表中,这样的话修改任何一个都会影响另外一个
>>> aList = [3, 5, 7]
>>> bList = aList[:]           #切片,浅复制
>>> aList == bList             #切片刚完成的瞬间,bList和aList中包含同样的元素引用
True
>>> bList[1] = 8               #列表中只包含可哈希对象,修改bList时不影响aList
>>> bList
[3, 8, 7]
>>> aList
[3, 5, 7]
>>> aList = [3, [5], 7]        #列表aList中包含可变的列表对象
>>> bList = aList[:]           #切片
>>> bList[1].append(6)         #调用子列表的append()方法,这个方法是原地操作的
>>> bList
[3, [5, 6], 7]
>>> aList                      #aList受到影响
[3, [5, 6], 7]
  • 标准库copy中的deepcopy()函数实现深复制。所谓深复制,是指对原列表中的元素进行递归,把所有的值都复制到新列表中,对嵌套的子列表不再是复制引用。新列表和原列表是互相独立,修改任何一个都不会影响另外一个
>>> aList = [3, [5], 7]
>>> import copy
>>> bList = copy.deepcopy(aList) #深赋值,递归复制,直到遇到可哈希对象
                           #aList和bList完全独立,互相不影响
>>> aList == bList
True
>>> aList is bList
False
>>> bList[1].append(6)         #修改bList不会影响aList
>>> bList
[3, [5, 6], 7]
>>> aList
[3, [5], 7]

列表排序

使用列表对象的sort()方法
>>> aList = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> import random
>>> random.shuffle(aList)
>>> aList
[3, 4, 15, 11, 9, 17, 13, 6, 7, 5]
>>> aList.sort()                            #默认是升序排序
>>> aList
[3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> aList.sort(reverse=True)              #降序排序
>>> aList
[17, 15, 13, 11, 9, 7, 6, 5, 4, 3]
>>> aList.sort(key=lambda x:len(str(x)))  #按转换成字符串的长度排序
>>> aList
[9, 7, 6, 5, 4, 3, 17, 15, 13, 11]
使用内置函数sorted()
  • 使用内置函数sorted()对列表进行排序并返回新列表
>>> aList
[9, 7, 6, 5, 4, 3, 17, 15, 13, 11]
>>> sorted(aList)                            #升序排序
[3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> sorted(aList,reverse=True)             #降序排序
[17, 15, 13, 11, 9, 7, 6, 5, 4, 3]
使用reverse()方法
  • 列表对象的reverse()方法将元素原地逆序
>>> aList = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> aList.reverse()
>>> aList
[17, 15, 13, 11, 9, 7, 6, 5, 4, 3]
使用内置函数reversed()
  • 使用内置函数reversed()对列表元素进行逆序排列并返回迭代对象
>>> aList = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> newList = reversed(aList)         #返回reversed对象
>>> list(newList)                     #把reversed对象转换成列表
[17, 15, 13, 11, 9, 7, 6, 5, 4, 3]
>>> for i in newList:
    print(i, end=' ')                 #这里没有输出内容
                                      #迭代对象已遍历结束
>>> newList = reversed(aList)         #重新创建reversed对象
>>> for i in newList:
    print(i, end=' ')
17 15 13 11 9 7 6 5 4 3

常用的内置函数

all()和any()
  • all()函数用来测试列表、元组等序列对象以及map对象、zip对象等类似对象中是否所有元素都等价于True,any()函数用来测试序列或可迭代对象中是否存在等价于True的元素。
>>> all([1,2,3])
True
>>> all([0,1,2,3])
False
>>> any([0,1,2,3])
True
>>> any([0])
False
len()
  • 返回列表中的元素个数,同样适用于元组、字典、集合、字符串等
max() min()
  • 返回列表中的最大或最小元素,同样适用于元组、字典、集合、range对象等
sum()
  • 对列表的元素进行求和运算,对非数值型列表运算需要指定start参数,同样适用于元组、range
>>> sum(range(1, 11))      #sum()函数的start参数默认为0
55
>>> sum(range(1, 11), 5)   #指定start参数为5,等价于5+sum(range(1,11))
60
>>> sum([[1, 2], [3], [4]], [])    #这个操作占用空间较大,慎用
[1, 2, 3, 4]
zip()
  • 返回可迭代的zip对象
>>> aList = [1, 2, 3]
>>> bList = [4, 5, 6]
>>> cList = zip(aList, bList)                 #返回zip对象
>>> cList
<zip object at 0x0000000003728908>
>>> list(cList)                       #把zip对象转换成列表
[(1, 4), (2, 5), (3, 6)]
enumerate()
  • 枚举列表元素,返回枚举对象,其中每个元素为包含下标和值的元组。该函数对元组、字符串同样有效
>>> for item in enumerate('abcdef'):
    print(item)

(0, 'a')
(1, 'b')
(2, 'c')
(3, 'd')
(4, 'e')
(5, 'f')

列表推导式

>>> sum([2**i for i in range(64)])
18446744073709551615
>>> int('1'*64, 2)
18446744073709551615
>>> vec = [[1,2,3], [4,5,6], [7,8,9]] 
>>> [num for elem in vec for num in elem] 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> aList = [-1,-4,6,7.5,-2.3,9,-11]
>>> [i for i in aList if i>0]
>>> [(x, y) for x in range(3) for y in range(3)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
>>> [(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
>>> matrix = [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] 
>>> [[row[i] for row in matrix] for i in range(4)] 
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] 
>>> list(map(list, zip(*matrix)))
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
>>> [f(v) for v in [2, 3, 4, -1] if v>0]
[4, 4, 16]
>>> [v**2 if v%2 == 0 else v+1 for v in [2, 3, 4, -1] if v>0]
[4, 4, 16]
>>> x = list(range(10))
>>> [item>5 for item in x]
[False, False, False, False, False, False, True, True, True, True]

元组

  • 元组和列表类似,但属于不可变序列,元组一旦创建,用任何方法都不可以修改其元素
  • 元组的定义方式和列表相同,但定义时所有元素是放在一对圆括号“()”中,而不是方括号中

元组的创建与删除

=赋值
>>> a_tuple = ('a', 'b', 'mpilgrim', 'z', 'example')
>>> a_tuple
('a', 'b', 'mpilgrim', 'z', 'example')
>>> a = (3)
>>> a
3
>>> a = (3,)             #包含一个元素的元组,最后必须多写个逗号
>>> a
(3,)
>>> a = 3,               #也可以这样创建元组
>>> a
(3,)
>>> x = ()               #空元组
使用tuple将其他序列转换为元组
>>> tuple('abcdefg')                    #把字符串转换为元组
('a', 'b', 'c', 'd', 'e', 'f', 'g')
>>> aList
[-1, -4, 6, 7.5, -2.3, 9, -11]
>>> tuple(aList)                        #把列表转换为元组
(-1, -4, 6, 7.5, -2.3, 9, -11)
>>> s = tuple()                         #空元组
>>> s
()
  • 使用del可以删除元组对象,不能删除元组中的元素

  • 元组一旦定义就不允许更改

  • 元组没有append()、extend()和insert()等方法,无法向元组中添加元素

  • 元组没有remove()或pop()方法,也无法对元组元素进行del操作,不能从元组中删除元素

元组和列表的区别

  • 元组的速度比列表更快。如果定义了一系列常量值,而所需做的仅是对它进行遍历,那么一般使用元组而不用列表
  • 元组对不需要改变的数据进行**“写保护”**将使得代码更加安全
  • 元组可用作字典的“键”,也可以作为集合的元素。列表不能作为字典的“键”,包含列表、字典、集合或其他类型可变对象的元组也不能做字典的“键”
  • 如果元组中包含列表或其他类型的可变对象,这些对象是可变的,但元组元素的引用仍是不可变的
>>> x = ([1, 2], 3)
>>> x[0][0] = 5
>>> x
([5, 2], 3)
>>> x[0].append(8)
>>> x
([5, 2, 8], 3)
>>> x[0] = x[0]+[10]
TypeError: 'tuple' object does not support item assignment
>>> x
([5, 2, 8], 3)

序列解包

  • 使用序列解包功能对多个变量同时赋值
>>> x, y, z = 1, 2, 3             #多个变量同时赋值
>>> v_tuple = (False, 3.5, 'exp')
>>> (x, y, z) = v_tuple
>>> x, y, z = v_tuple
>>> x, y, z = range(3)            #可以对range对象进行序列解包
>>> x, y, z = iter([1, 2, 3])     #使用迭代器对象进行序列解包
>>> x, y, z = map(str, range(3))  #使用可迭代的map对象进行序列解包
>>> a, b = b, a                   #交换两个变量的值
>>> x, y, z = sorted([1, 3, 2])   #sorted()函数返回排序后的列表
>>> a, b, c = 'ABC'               #字符串也支持序列解包
>>> x = [1, 2, 3, 4, 5, 6]
>>> x[:5] = map(str, range(5))    #切片也支持序列解包
  • 序列解包遍历多个序列
>>> keys = ['a', 'b', 'c', 'd']
>>> values = [1, 2, 3, 4]
>>> for k, v in zip(keys, values):
	  print((k, v), end=' ')

('a', 1) ('b', 2) ('c', 3) ('d', 4) 
  • 利用 * 表达式获取单个变量中的多个元素
>>> print(*[1, 2, 3], 4, *(5, 6))
1 2 3 4 5 6
>>> *range(4),4
(0, 1, 2, 3, 4)
>>> {*range(4), 4, *(5, 6, 7)}
{0, 1, 2, 3, 4, 5, 6, 7}
>>> {'x': 1, **{'y': 2}}
{'y': 2, 'x': 1}

生成器推导式

  • 生成器推导式的结果是一个生成器对象。使用生成器对象的元素时,可以根据需要将其转化为列表或元组,也可以使用生成器对象__next__()方法或内置函数next()进行遍历,或者直接将其作为迭代器对象来使用

  • 生成器对象具有惰性求值的特点,只在需要时生成新元素,空间占用非常少,尤其适合大数据处理的场合

  • 不管用哪种方法访问生成器对象,都无法再次访问已访问过的元素

  • 使用生成器对象__next__()方法或内置函数next()进行遍历

>>> g = ((i+2)**2 for i in range(10))  #创建生成器对象
>>> g
<generator object <genexpr> at 0x0000000003095200>
>>> tuple(g)                           #将生成器对象转换为元组
(4, 9, 16, 25, 36, 49, 64, 81, 100, 121)
>>> list(g)             #生成器对象已遍历结束,没有元素了
[] 
>>> g = ((i+2)**2 for i in range(10))  #重新创建生成器对象
>>> g.__next__()        #使用生成器对象的__next__()方法获取元素
4
>>> g.__next__()        #获取下一个元素
9
>>> next(g)             #使用函数next()获取生成器对象中的元素
16
  • 使用for循环直接迭代生成器对象中的元素
>>> g = ((i+2)**2 for i in range(10))
>>> for item in g:                #使用循环直接遍历生成器对象中的元素
    print(item, end=' ')

4 9 16 25 36 49 64 81 100 121 

字典

  • 字典是无序、可变序列
  • 定义字典时,每个元素的键和值用冒号分隔,元素之间用逗号分隔,所有的元素放在一对大括号“{}”中
  • 字典中的键可以为任意不可变数据,比如整数、实数、复数、字符串、元组等等

字典的创建与删除

=赋值
  • 使用=将一个字典赋值给一个变量
>>> a_dict = {'server': 'db.diveintopython3.org', 'database': 'mysql'}
>>> a_dict
{'database': 'mysql', 'server': 'db.diveintopython3.org'}
>>> x = {}                     #空字典
>>> x
{}
使用dict
  • 使用dict利用已有数据创建字典
>>> keys = ['a', 'b', 'c', 'd']
>>> values = [1, 2, 3, 4]
>>> dictionary = dict(zip(keys, values))
>>> dictionary
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
  • 使用dict根据给定的键、值创建字典、
>>> d = dict(name='Dong', age=37)
>>> d
{'name': 'Dong', 'age': 37}
  • 以给定内容为键,创建值为空的字典
>>> adict = dict.fromkeys(['name', 'age', 'sex'])
>>> adict
{'name': None, 'age': None, 'sex': None}
  • 可以使用del删除整个字典

字典元素的读取

以键为下标
  • 以键作为下标可以读取字典元素,若键不存在则抛出异常
>>> aDict = {'name':‘Zhang', 'sex':'male', 'age':20}
>>> aDict['name']
‘Zhang'
>>> aDict['tel']                     #键不存在,抛出异常
Traceback (most recent call last):
  File "<pyshell#53>", line 1, in <module>
    aDict['tel']
KeyError: 'tel'
  • 使用字典对象的get()方法获取指定键对应的值,并且可以在键不存在的时候返回指定值
>>> print(aDict.get('address'))
None
>>> print(aDict.get('address', 'OUC'))
OUC
  • 使用字典对象的items()方法可以返回字典的元素
  • 使用字典对象的keys()方法可以返回字典的“键”
  • 使用字典对象的values()方法可以返回字典的“值”
>>> aDict={'name':'Zhang', 'sex':'male', 'age':20}
>>> for item in aDict.items():     #输出字典中所有元素
    print(item)

('age', 20)
('name', 'Zhang')
('sex', 'male')
>>> for key in aDict:              #不加特殊说明,默认输出“键”
    print(key)

age
name
sex
>>> for key, value in aDict.items():       #序列解包用法
    print(key, value)

age 20
name Zhang
sex male
>>> aDict.keys()                           #返回所有“键”
dict_keys(['name', 'sex', 'age'])
>>> aDict.values()                         #返回所有“值”
dict_values(['Zhang', 'male', 20])

字典元素的添加

  • 当以指定键为下标为字典赋值时:1)若键存在,则可以修改该键的值;2)若不存在,则表示添加一个键、值对。
>>> aDict['age'] = 19                 #修改元素值
>>> aDict
{'age': 19, 'name': 'Zhang', 'sex': 'male'}
>>> aDict['address'] = 'OUC'        #增加新元素
>>> aDict
{'age': 19, 'address': 'OUC', 'name': 'Zhang', 'sex': 'male'}
  • 使用字典对象的update()方法将另一个字典的键、值对添加到当前字典对象
>>> aDict.update({'score':[98, 97]})
>>> aDict.items()
dict_items([('age', 19), ('address', 'OUC'), ('name', 'Zhang'), ('score', [98, 97]), ('sex', 'male')])
>>> aDict.update({'a':'a','b':'b'})
>>> aDict
{'a': 'a', 'address': 'OUC', 'age': 19, 'b': 'b', 'name': 'Zhang', 'score': [98, 97], 'sex': 'male'}

字典元素的删除

  • 使用del删除字典中指定键的元素
  • 使用字典对象的clear()方法来删除字典中所有元素
  • 使用字典对象的pop()方法删除并返回指定键的元素
  • 使用字典对象的popitem()方法删除并返回字典中的一个元素

字典推导式

>>> s = {x:x.strip() for x in ('  he  ', 'she    ', '    I')}
>>> s
{'  he  ': 'he', '    I': 'I', 'she    ': 'she'}
>>> for k, v in s.items():
    print(k, ':', v)

  he   : he
    I : I
she     : she 
>>> {i:str(i) for i in range(1, 5)}
{1: '1', 2: '2', 3: '3', 4: '4'}
>>> x = ['A', 'B', 'C', 'D']
>>> y = ['a', 'b', 'b', 'd']
>>> {i:j for i,j in zip(x,y)}
{'A': 'a', 'B': 'b', 'C': 'b', 'D': 'd'}

集合

  • 集合是无序、可变序列,使用一对大括号界定,元素不可重复,同一个集合中每个元素都是唯一的
  • 集合中只能包含数字、字符串、元组等不可变类型(或者说可哈希)的数据,而不能包含列表、字典、集合等可变类型的数据

集合的创建

  • 直接将集合赋值给变量
>>> a = {3, 5}
  • 使用set将其他类型数据转换为集合
>>> a_set = set(range(8,14))
>>> a_set
{8, 9, 10, 11, 12, 13}
>>> b_set = set([0, 1, 2, 3, 0, 1, 2, 3, 7, 8])   #自动去除重复
>>> b_set
{0, 1, 2, 3, 7, 8}
>>> c_set = set()                                 #空集合
>>> c_set
set()

集合的删除

  • 当不再使用某个集合时,可以使用del命令删除整个集合。集合对象的pop()方法弹出并删除其中一个元素,remove()方法直接删除指定元素,clear()方法清空集合
>>> a = {1, 4, 2, 3}
>>> a.pop()
1
>>> a.pop()
2
>>> a
{3, 4}
>>> a.add(2)
>>> a
{2, 3, 4}
>>> a.remove(3)
>>> a
{2, 4}

集合运算

  • 交集、并集、差集、对称差集等运算
>>> a_set = set([8, 9, 10, 11, 12, 13])
>>> b_set = {0, 1, 2, 3, 7, 8}
>>> a_set | b_set                             #并集
{0, 1, 2, 3, 7, 8, 9, 10, 11, 12, 13}
>>> a_set & b_set                             #交集
{8}
>>> a_set - b_set                             #差集
{9, 10, 11, 12, 13}
>>> a_set ^ b_set                             #对称差集
{0, 1, 2, 3, 7, 9, 10, 11, 12, 13}
  • 集合包含关系测试
>>> x = {1, 2, 3}
>>> y = {1, 2, 5}
>>> z = {1, 2, 3, 4}
>>> x < y                                #比较集合大小/包含关系
False
>>> x < z                                #真子集
True
>>> y < z
False
>>> {1, 2, 3} <= {1, 2, 3}               #子集
True

集合推导式

>>> s = {x.strip() for x in ('  he  ', 'she    ', '    I')}
>>> s
{'I', 'she', 'he'}

内置方法sorted

  • 列表对象提供了sort()方法支持原地排序,而内置函数sorted()返回新列表,并不对原列表进行任何修改
  • sorted()方法可以对列表、元组、字典、range对象等进行排序
  • 列表的sort()方法和内置函数sorted()都支持key参数实现复杂排序要求
>>> persons = [{'name':'Dong', 'age':37}, 
               {'name':'Zhang', 'age':40},
               {'name':'Li', 'age':50},
               {'name':'Dong', 'age':43}]
>>> print(persons)
[{'name': 'Dong', 'age': 37}, {'name': 'Zhang', 'age': 40}, {'name': 'Li', 'age': 50}, {'name': 'Dong', 'age': 43}]
#使用key来指定排序依据,先按姓名升序排序,姓名相同的按年龄降序排序
>>> print(sorted(persons, key=lambda x:(x['name'], -x['age'])))
[{'name': 'Dong', 'age': 43}, {'name': 'Dong', 'age': 37}, {'name': 'Li', 'age': 50}, {'name': 'Zhang', 'age': 40}]>>> phonebook = {'Linda':'7750', 'Bob':'9345', 'Carol':'5834'}
>>> from operator import itemgetter
>>> sorted(phonebook.items(), key=itemgetter(1))
                                     #按字典中元素值进行排序
[('Carol', '5834'), ('Linda', '7750'), ('Bob', '9345')]
>>> sorted(phonebook.items(), key=itemgetter(0))
                                     #按字典中元素的键进行排序
[('Bob', '9345'), ('Carol', '5834'), ('Linda', '7750')]
>>> gameresult = [['Bob', 95.0, 'A'], ['Alan', 86.0, 'C'], 
                  ['Mandy', 83.5, 'A'], ['Rob', 89.3, 'E']]
>>> sorted(gameresult, key=itemgetter(0, 1))
                             #按姓名升序,姓名相同按分数升序排序
[['Alan', 86.0, 'C'], ['Bob', 95.0, 'A'], ['Mandy', 83.5, 'A'], ['Rob', 89.3, 'E']]
>>> sorted(gameresult, key=itemgetter(1, 0))
                             #按分数升序,分数相同的按姓名升序排序
[['Mandy', 83.5, 'A'], ['Alan', 86.0, 'C'], ['Rob', 89.3, 'E'], ['Bob', 95.0, 'A']]
>>> sorted(gameresult, key=itemgetter(2, 0))
                             #按等级升序,等级相同的按姓名升序排序
[['Bob', 95.0, 'A'], ['Mandy', 83.5, 'A'], ['Alan', 86.0, 'C'], ['Rob', 89.3, 'E']]
>>> gameresult = [{'name':'Bob', 'wins':10, 'losses':3, 'rating':75.0},
                  {'name':'David', 'wins':3, 'losses':5, 'rating':57.0},
                  {'name':'Carol', 'wins':4, 'losses':5, 'rating':57.0},
                  {'name':'Patty', 'wins':9, 'losses':3, 'rating':72.8}]
>>> sorted(gameresult, key=itemgetter('wins', 'name')) 
#按'wins'升序,该值相同的按'name'升序排序
[{'name': 'David', 'wins': 3, 'losses': 5, 'rating': 57.0}, {'name': 'Carol', 'wins': 4, 'losses': 5, 'rating': 57.0}, {'name': 'Patty', 'wins': 9, 'losses': 3, 'rating': 72.8}, {'name': 'Bob', 'wins': 10, 'losses': 3, 'rating': 75.0}]
>>> list1 = ["what", "I'm", "sorting", "by"]
>>> list2 = ["something", "else", "to", "sort"]
>>> pairs = zip(list1, list2)
>>> pairs = sorted(pairs)
>>> pairs
[("I'm", 'else'), ('by', 'sort'), ('sorting', 'to'), ('what', 'something')]
>>> result = [x[1] for x in pairs]
>>> result
['else', 'sort', 'to', 'something']
>>> from random import randint
>>> x = [randint(1,100) for i in range(20)]
>>> x
[19, 32, 76, 82, 23, 63, 38, 50, 20, 30, 39, 14, 19, 50, 81, 27, 77, 12, 55, 29]
>>> sorted(x, key=lambda item:item%2==0)
[19, 23, 63, 39, 19, 81, 27, 77, 55, 29, 32, 76, 82, 38, 50, 20, 30, 14, 50, 12]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python爬虫笔记python基础知识,以TXT文件呈现 一、概述 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言Python为我们提供了非常完善的基础代码库,覆盖了网络、文件、GUI、数据库、文本等大量内容,被形象地称作“内置电池(batteries included)”。用Python开发,许多功能不必从零编写,直接使用现成的即可。 龟叔给Python的定位是“优雅”、“明确”、“简单”,所以Python程序看上去总是简单易懂,初学者学Python,不但入门容易,而且将来深入下去,可以编写那些非常非常复杂的程序。 那Python适合开发哪些类型的应用呢? 首选是网络应用,包括网站、后台服务等等; - PythonWeb 其次是许多日常需要的小工具,包括系统管理员需要的脚本任务等等; - Python 另外就是把其他语言开发的程序再包装起来,方便使用。 - 胶水语言 在 爬虫 科学计算 等领域有独特优势 AI Python的优点 简单易学 完善的语言特性 天然开源 丰富的社区支持 Python的缺点。 第一个缺点就是运行速度慢,和C程序相比非常慢,因为Python是解释型语言,你的代码在执行时会一行一行地翻译成CPU能理解的机器码,这个翻译过程非常耗时,所以很慢。而C程序是运行前直接编译成CPU能执行的机器码,所以非常快。 但是大量的应用程序不需要这么快的运行速度,因为用户根本感觉不出来。例如开发一个下载MP3的网络应用程序,C程序的运行时间需要0.001秒,而Python程序的运行时间需要0.1秒,慢了100倍,但由于网络更慢,需要等待1秒,你想,用户能感觉到1.001秒和1.1秒的区别吗?这就好比F1赛车和普通的出租车在北京三环路上行驶的道理一样,虽然F1赛车理论时速高达400公里,但由于三环路堵车的时速只有20公里,因此,作为乘客,你感觉的时速永远是20公里。 第二个缺点就是代码不能加密。如果要发布你的Python程序,实际上就是发布源代码,这一点跟C语言不同,C语言不用发布源代码,只需要把编译后的机器码(也就是你在Windows上常见的xxx.exe文件)发布出去。要从机器码反推出C代码是不可能的,所以,凡是编译型的语言,都没有这个问题,而解释型的语言,则必须把源码发布出去。 二、安装配置 安装包下载地址: http://www.python.org/download/ Python目前分为两大版本,互不兼容: 2.x.x 3.x.x 下载的时候要注意区分 根据需要的版本进行下载 目前两者都有所使用 双击安装 设置环境变量: 将python安装位置配置到PATH环境变量下。 三、运行方式 shell方式: 在cmd窗口中输入python进入命令行模式 在其中以交互式方式执行 shell方式调用py文件: 在文件中编写Python脚本 文件后缀为.py 进入该文件所在目录 直接执行./xxx.py IDE模式: pycharm pyDev for Eclipse **Python编码 Python默认读取py文件时采用的编码格式是 ASCII 格式,如果文件不是该格式很可能出现乱码问题造成异常。 解决方法为只要在文件开头加入 # -*- coding: UTF-8 -*- 或者 #coding=utf-8 来通知Python解释器在读取文件时采用的编码集 四、标识符 在 Python 中,所有标识符可以包括英文、数字以及下划线(_),但不能以数字开头。 Python 中的标识符是区分大小写的。 以下划线开头的标识符是有特殊意义的。 以单下划线开头 _foo 的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用 from xxx import * 而导入; 以双下划线开头的 __foo 代表类的私有成员;以双下划线开头和结尾的 __foo__ 代表 Python 里特殊方法专用的标识,如 __init__() 代表类的构造函数。 五、语言细节 1.语句 Python通常一行为一条语句 不需要分号标识 Python 可以同一行显示多条语句,方法是用分号 ; 案例: print 'hello';print 'runoob'; 也可以使用反斜杠将一行语句分为多行解释: 案例: total = item_one + \.....................................................

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值