美文网首页
《自学学门手艺》读书笔记14

《自学学门手艺》读书笔记14

作者: 专注执行 | 来源:发表于2019-12-21 19:23 被阅读0次

          上个月11月21日完成了字符串章节的阅读,心中非常欢喜,连滚带爬总算翻过了一道坎,想必接下来的内容能顺利些,哪成想要读完容器这章,也势必要再费一番周折。消极的话到此为止,还是继续正文摘要吧。

    本章主讲内容是数据容器(Container),包括字符串、由 range() 函数生成的等差数列、列表(List)、元组(Tuple)、集合(Set)、字典(Dictionary)。根据不同的分类方法,这些容器又分为可变容器(Mutable)和不可变容器(Immutable)。可变的有列表、集合、字典;不可变的有字符串、range() 生成的等差数列、元组。集合,又分为 Set 和 Frozen Set;其中,Set 是可变的,Frozen Set 是不可变的。字符串、由 range() 函数生成的等差数列、列表、元组是有序类型(Sequence Type),而集合与字典是无序的。另外,集合没有重合元素。分类汇总图表如下:

    容器分类

    迭代

    数据容器里的元素是可以被迭代的(Iterable),为便于处理,它们其中包含的元素,可以被逐个访问。由于数据容器的可迭代性,加上操作符 in,在 Python 语言里写循环格外容易且方便(以字符串这个字符的容器作为例子):

    for c in 'Python':
      print(c)
    P
    y
    t
    h
    o
    n

    在 Python 中,简单的 for 循环,只需要指定一个次数就可以了,因为有 range() 这个函数:

    for i in range(10):
      print(i)
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

    Python 也不只有 for 循环,还有 while 循环,在必要的时候可以写复杂的计数器。

    列表(List)

    列表和字符串一样,是个有序类型(Sequence Type)的容器,其中包含着有索引编号的元素。列表中的元素可以是不同类型。

    列表的生成

    生成一个列表,有以下四种方式:

    a_list = []
    b_list = [1, 2, 3]
    list(), or list(iterable)            # 这是 Type Casting
    [(expression with x) for x in iterable]

    列表的操作符

    列表的操作符和字符串一样,因为它们都是有序容器。列表的操作符有:

    拼接:+(与字符串不一样的地方是,不能用空格 ' ' 了)
    复制:*
    逻辑运算:in 和 not in,<、<=、>、>=、!=、==

    两个列表可以被比较,即,可以进行逻辑运算;比较方式也跟字符串一样,从两个列表各自的第一个元素开始逐个比较,“一旦决出胜负马上停止”

    根据索引提取列表元素

    列表当然也可以根据索引操作,但由于列表是可变序列,所以,不仅可以提取,还可以删除,甚至替换。

    运行下列语句:

    import random
    n = 3
    a_list = [random.randrange(65, 91) for i in range(n)]
    b_list = [chr(random.randrange(65, 91)) for i in range(n)]
    print(a_list)
    c_list = a_list + b_list + a_list * 2
    print(c_list)

    print()
    # 根据索引提取(Slicing)
    print(c_list[3])        # 返回索引值为 3 的元素值
    print(c_list[:])        # 相当于 c_list,返回整个列表
    print(c_list[5:])      # 从索引为 5 的值开始直到末尾
    print(c_list[:3])      # 从索引 0 开始,直到索引 3 之前(不包括 3)
    print(c_list[2:6])      # 从索引 2 开始,直到索引 6 之前(不包括 6)

    print()
    # 根据索引删除
    del c_list[3]
    print(c_list)          # del 是个命令,del c_list[3] 是一个语句;不能这么写:print(del c_list[3])
    del c_list[5:8]
    print(c_list)

    print()
    # 根据索引替换
    c_list[1:5:2] = ['a', 2]  # s[start:stop:step] = t,跟 range 的三个参数类似;
                            # len(t) = len([start:stop:step]) 必须为真

    输出结果如下:

    [77, 66, 79]
    [77, 66, 79, 'L', 'Z', 'R', 77, 66, 79, 77, 66, 79]

    L
    [77, 66, 79, 'L', 'Z', 'R', 77, 66, 79, 77, 66, 79]
    ['R', 77, 66, 79, 77, 66, 79]
    [77, 66, 79]
    [79, 'L', 'Z', 'R']

    [77, 66, 79, 'Z', 'R', 77, 66, 79, 77, 66, 79]
    [77, 66, 79, 'Z', 'R', 77, 66, 79]

    [77, 'a', 79, 2, 'R', 77, 66, 79]

    需要注意,列表(List)是可变序列,而字符串(str)是不可变序列,对字符串来说,虽然也可以根据索引提取,但没办法根据索引删除或者替换。

    字符串常量(String Literal)是不可变有序容器,虽然字符串也有一些 Methods 可用,但那些 Methods 都不改变它们自身,而是在操作后返回一个值给另外一个变量。而对于列表这种可变容器,我们可以对它进行操作,结果是它本身被改变了。见如下示例:

    s = 'Python'
    L = list(s)
    print(s)
    print(L)
    del L[2]
    print(L) # 用 del 对 L 操作之后,L 本身少了 1 个元素

    返回结果

    Python
    ['P', 'y', 't', 'h', 'o', 'n']
    ['P', 'y', 'h', 'o', 'n']

    列表可用的内建函数

    列表和字符串都是容器,它们可使用的内建函数也其实都是一样的:

    len()
    max()
    min()

    示例:

    import random
    n = 3

    # 生成 3 个随机数,构成一个列表
    a_list = [random.randrange(65, 91) for i in range(n)]
    b_list = [chr(random.randrange(65, 91)) for i in range(n)]
    print(a_list)
    print(b_list)

    # 列表可以使用操作符 + 和*
    c_list = a_list + b_list + a_list * 2
    print(c_list)

    a_list *= 3
    print(a_list)

    # 内建函数操作 len()、max()、min()
    print(len(c_list))
    print(max(b_list)) # 内建函数内部做了异常处理,可以比较字符和数字 —— 初学者最讨厌这种事情了……
    print(min(b_list)) # 注意,max() 和 min() 应用的是 b_list, len() 应用的是 c_list —— 请自行找到对应的 list 进行分析。

    print('X' not in b_list)

    返回结果

    [89, 84, 85]
    ['X', 'B', 'X']
    [89, 84, 85, 'X', 'B', 'X', 89, 84, 85, 89, 84, 85]
    [89, 84, 85, 89, 84, 85, 89, 84, 85]
    12
    X
    B
    False

    Methods

    字符串常量和 range() 都是不可变的(Immutable);而列表则是可变类型(Mutable type),所以,它最起码可以被排序 —— 使用 sort() method ,如果列表中的元素全都是由字符串构成的,当然也可以排序.

    注意:被比较的元素应该是同一类型 ,不是由同一种数据类型元素构成的列表,不能使用 sort() Method。

    可变序列还有一系列可用的 Methods:a.append(),a.clear(),a.copy(),a.extend(t),a.insert(i,x),a.pop([i]),a.remove(x),a.reverse()
    示例:

    import random
    n = 3
    a_list = [random.randrange(65, 91) for i in range(n)]
    b_list = [chr(random.randrange(65, 91)) for i in range(n)]
    print(a_list)
    c_list = a_list + b_list + a_list * 2
    print(c_list)

    # 在末尾追加一个元素
    c_list.append('100')
    print(c_list)

    # 清空序列
    print()
    print(a_list)
    a_list.clear()
    print(a_list)

    print()
    # 拷贝一个列表
    d_list = c_list.copy()
    print(d_list)
    del d_list[6:8]
    print(d_list)
    print(c_list)            # 对一个拷贝操作,不会更改 “原件”

    print()
    # 演示拷贝 .copy() 与赋值 = 的不同
    e_list = d_list
    del e_list[6:8]
    print(e_list)
    print(d_list)            # 对 e_list 操作,相当于对 d_list 操作

    # 在末尾追加一个列表
    print()
    print(a_list)
    a_list.extend(c_list)      # 相当于 a_list += c_list
    print(a_list)

    # 在某索引位置插入一个元素
    print()
    print(a_list)
    a_list.insert(1, 'example')  # 在索引 1 的位置插入 'example'
    a_list.insert(3, 'example')  # 在索引 3 的位置插入 'example';
    print(a_list)

    # 排序

    # a_list.sort() 这一句会出错,因为当前列表中的元素,是 int 和 str 混合的。

    print()
    print(a_list)
    a_list.reverse()
    print(a_list)
    x = a_list.reverse() # reverse() 只对当前序列操作,并不返回一个逆序列表;返回值是 None
    print(x)

    返回结果

    [90, 88, 73]
    [90, 88, 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73]
    [90, 88, 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']

    [90, 88, 73]
    []

    [90, 88, 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']
    [90, 88, 73, 'T', 'N', 'Y', 73, 90, 88, 73, '100']
    [90, 88, 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']

    [90, 88, 73, 'T', 'N', 'Y', 88, 73, '100']
    [90, 88, 73, 'T', 'N', 'Y', 88, 73, '100']

    []
    [90, 88, 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']

    [90, 88, 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']
    [90, 'example', 88, 'example', 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']

    [90, 'example', 88, 'example', 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']
    ['100', 73, 88, 90, 73, 88, 90, 'Y', 'N', 'T', 73, 'example', 88, 'example', 90]
    None

    命令del,Method a.pop([i])和a.remove(x)都与删除单个元素相关,请注意它们之间的区别。

    import random
    n = 3
    a_list = [random.randrange(65, 91) for i in range(n)]
    print(a_list)

    # 插入
    print()
    a_list.insert(1, 'example')  # 在索引 1 的位置插入 'example'

    # 删除
    print()
    print(a_list)
    a_list.remove('example')      # 去除 'example' 这个元素,如果有多个 'example',只删除第一个
    print(a_list)

    # pop() 删除并返回被删除的值

    print()
    print(a_list)
    p = a_list.pop(2)      # 去除索引为 2 的元素,且返回元素的值,赋值给 p
    print(a_list)
    print(p)

    # pop() 与 del,或者 remove() 的区别
    print()
    a_list.insert(2, 'example')
    a_list.insert(2, 'example')
    print(a_list)
    del a_list[2]
    print(a_list)

    print()
    print(a_list.remove('example')) # a_list.remove() 这个 Method 的返回值是 None
    print(a_list)

    返回结果:

    [88, 84, 69]

    [88, 'example', 84, 69]
    [88, 84, 69]

    [88, 84, 69]
    [88, 84]
    69

    [88, 84, 'example', 'example']
    [88, 84, 'example']

    None
    [88, 84]

    容器特性总结

    路漫漫其修远兮,唯有耐心随其愿。加油!

    相关文章

      网友评论

          本文标题:《自学学门手艺》读书笔记14

          本文链接:https://www.haomeiwen.com/subject/qcognctx.html