Advertisement

《像计算机科学家一样思考Python》学习笔记

阅读量:

目录

    • 前言

    • 重要的中英文互译

    • Python小白与大神的区别

      • 条件表达式
      • 列表高端操作
      • 收集关键词参数
    • 第一章

      • 何谓程序
      • 树立“值才是程序最基本的单位,而不是变量”的概念
      • 形式语言和自然语言
    • 第二章

      • 变量及命名
      • 表达式和语句的定义
      • 字符串可进行的数学操作
    • 第三章

      • 模块及其使用方法
      • 函数的定义
      • 形参与实参
      • 栈图
    • 第四章

    • 第五章

      • Python需要注意的运算符
      • 条件链(chained conditional)
      • 递归(Recursion)
      • 无限递归
      • 键盘输入
    • 第六章

      • isinstance()检查输入的类型
      • 调试的思想
    • 第八章

      • 搜索
      • in在字符串中的妙用
    • 第十章:列表

      • sum在列表中的妙用
      • 从列表中删除元素的方法
      • 列表和字符串
    • 第十二章:字典

      • 创建一个字典
      • 访问字典中的元素
      • len和in在字典中的应用
      • 如何查看一个变量是否是字典的键或值
      • 循环在字典中的应用
      • 字典使用案例:作为计数器
      • 已知“值”,如何查找“键”
    • 元组

      • 创建一个元组
      • 访问元组中的元素
      • 函数具有多个返回值时元组常常作为接受返回值的数据类型
      • 用元组充当可变数量形参
      • zip函数在元组中的应用
      • 字典和元组
    • 如何选择不同的数据结构

    • 运算重载在列表、元组、字符串中的运用

    • 用os模块操作文件

    • 关于类,常见而又不熟悉的操作

      • __str__方法进行调试
      • 多态函数

前言

作为计算机科学家,最重要的技能就是问题求解 。所谓问题求解,是发现问题、创造性思维解决方案以及清晰准确地表达解决方案 的能力。而学习编程的过程,正是训练问题求解能力的绝佳机会。

重要的中英文互译

  1. 可移植性(portability):程序的一种属性:可以在多种类型的计算机上运行。
  2. 解释器(interpreter):一个读取其他程序并执行其内容的程序。
  3. 记号(token):即语言的基本元素,比如单词、数字等;3+¥=6中的¥在数学表达式中就不是合法的记号;
  4. 语法(syntax):用于控制程序结构的规则。
  5. 语法分析(parse):检查程序并分析其语法结构。
复制代码
     常见的语法错误示例:
     SyntaxError:invalid token
     意思是:
     语法错误:无效的记号
    
    
      
      
      
      
    
  1. 交互模式(interactive mode):使用Python解释器的一种方式,在提示符之后键入代码。
  2. 脚本模式(script mode):使用Python解释器的另一种方式,从脚本中读入代码并运行它。
  3. 脚本(script):保存在文件中的程序。
  4. 异常(exception):程序运行中发现的错误。
  5. 模块(module):包含一组相关的函数的文件。
  6. 句点表示法(dot notation):调用模块中包含的函数的方法。

Python小白与大神的区别

条件表达式

复制代码
    if x > 0:
    	y = math.log(x)
    else:
    	y = float('man')
    
    
      
      
      
      
    

用条件表达式改写后:

复制代码
    y = math.log(x) if x > 0 else float('man')
    
    
      
    

列表高端操作

复制代码
    def test(t):
    	res = []
    	for s in t:
    		res.append('a')
    	return res
    
    
      
      
      
      
      
    

用列表的高端写法后:

复制代码
    def test(t):
    	return ['a' for s in t] # 列表可以通过[]赋值直接修改
    
    
      
      
    

但下面的写法是错误 的:

复制代码
    def test(t):
    res = []
    	return res.append('a') for s in t # 没有这种写法!!!
    会直接报错
    
    
      
      
      
      
    

收集关键词参数

我们知道*操作符作为形参,可以使函数接受任意个数的实参数量,如下函数:

复制代码
    def printall(*args):
    	print(args)
    
    
      
      
    

但实际上,*操作符不会收集带有关键字(名称)的实参,比如:

复制代码
    printall(1, 2.0, '3') # 这种写法可以调用
    printall(1, 2, third='3') # 这种写法会报错,不能接受带有关键字的实参
    
    
      
      
    

我们要记住,不带关键字的实参用*操作符收集为一个元组,带有关键字的实参用**操作符收集为一个字典,不能混收

复制代码
    >>> def printall(*args, **kwargs):
    >>>		print(args, kwargs)
    >>> printall(1, 2, third='3')
    (1, 2) {'third': '3'}
    
    
      
      
      
      
    

第一章

何谓程序

程序是指一组定义如何进行“计算”的指令集合,这里的“计算”具有丰富的内涵 ,可能是解方程根的数学运算;也可能是符号运算,比如搜索和替换文档的文本;或者图形相关的操作,如图像处理。

树立“值才是程序最基本的单位,而不是变量”的概念

值(value)是程序操作的最基本的东西,比如一个字母、数字或字符串 。值有不同的类型。基本上,在任何可以使用值的地方,都可以使用任意表达式
所谓变量,是指向一个值的名称;变量所具有的类型,就是其指向的值的类型
状态图 来看可能能更好地理解变量与值的关系:
下面的赋值语句的状态图如图所示:

复制代码
    message = 'And now for....' # 在此只为强调状态图,有些部分省略
    n = 17
    pi = 3.14....
    
    
      
      
      
    

在这里插入图片描述
状态图 可以明显看出,是“变量 指向 值 ”而不是“值 指向 变量 ”。

形式语言和自然语言

自然语言指的就是人们说的语言,比如普通话。
形式语言是人们为了特殊用途创造的语言,比如编程语言。

第二章

变量及命名

关于变量的定义在上一章已然介绍过,注意其与值的关系。对于变量的命名,一般是以小写字母开头,在多个单词之间用“_”连接。

表达式和语句的定义

表达式 是值、变量和操作符的集合。
语句 则指的是一段会产生效果的代码单元。

字符串可进行的数学操作

仅可以进行两个,一个是“*”,一个是“+”。

第三章

模块及其使用方法

比如说math模块,其中包含了一些数学函数。如果想使用其中的函数,按照如下步骤操作:

复制代码
    1、将模块导入到运行环境中;
    import math
    2、上述语句将会创建一个名为math的模块对象(module object),该对象中包含了已定义的函数和变量,以一个句点(.)分隔,这个格式称为句点表示法(dot notation)。
    height = math.sin(..)
    
    
      
      
      
      
    

函数的定义

以“def”关键词定义,如:

复制代码
    def print_ly(): #函数头
    	print(...) #函数体
    
    
      
      
    

需要注意的是,函数定义必须在使用它之前。

形参与实参

在函数定义时参数是形参,调用时的参数是实参。在下面这段代码的例子中,bruce是形参,m是实参:

复制代码
    def print_twice(bruce): # 定义
    	....
    
    print_twice(m) # 调用
    
    
      
      
      
      
    

另外,函数名本身也可以作为实参输入到函数中进行调用 ,如下例:

复制代码
    def do_twice(f):
    	f()
    	f()
    def print_spam():
    	print('spam')
    
    do_twice(print_spam) #将函数名作为实参输入到函数中进行调用a
    
    
      
      
      
      
      
      
      
    

栈图

用于跟踪哪些变量在哪些地方使用 ,每个函数使用一个 表达, 实际上在栈图中就是一个带着函数名称的盒子,里面有函数的参数和变量,比如下图中的__main__、cat_twice等
下面这个栈图的源程序的调用顺序是__main__调用cat_twicecat_twice又调用print_twice,是由上而下调用的过程。
在这里插入图片描述
在实际编写代码的过程中,直接接触到栈图的可能性不多,但是如果函数调用过程中发现了错误,Python会打印出函数名、调用它的函数的名称以及调用这个调用者的函数名,依次类推一直到__main__,如下例:
在这里插入图片描述
上图是写程序过程中常见错误,实际上它也是一个**回溯(Traceback)**的过程。它的顺序和栈图的顺序一致,表明了依次调用的关系,当前执行的有错误的函数或代码在最底部

第四章

1、封装(encapsulation):指的就是把一段代码用函数包裹起来(有无形参均可) ,好处除了给这段代码一个名称以增加可读性之外,还有就是需要重复使用这段代码时,调用一次函数比辅助粘贴这段代码要快得多。
2、泛化(generalization):听起来很玄,实际上就是重新定义一个已有的函数,给它多加几个形参 。如下所示:

复制代码
    def square(t):
    ....
    
    
      
      
    

对它进行泛化(重新定义、增加参数)

复制代码
    def square(t,length):
    ....
    
    
      
      
    

3、重构(refactoring):指的是重新组织程序,以改善接口,提高代码复用 ,一个好的函数,其形参应该是不多不少的,既能满足需求,也不需要人输入很多无必要的参数——如果能事先确定的经验参数或是按某种规则确定的参数,可体现在函数体而不是函数形参中。
4、实际上,写程序 的过程也被称为开发计划(development plan)这个思路应该是
【1】针对需求,直接写一些由上而下的程序,不需要考虑将其封装成函数;
【2】一旦程序成功运行,识别出其中完整的一部分,将它封装到一个函数中,并对函数进行合适的命名;
【3】泛化这个函数,添加合适的形参;
【4】对写好的程序重复以上三个步骤,直到得到一组可行的函数。
【5】完成封装和泛化后,对得到的一组函数思考是否有通过重构来改善程序的机会。例如,如果发现程序中有几处地方有相似的代码,可以考虑将它们抽取出来做一个合适的通用函数。

封装、泛化都比较好理解,下面给出一个对重构的理解例子

复制代码
    下面是两个函数,可以不考虑它们的作用,光从字面上来看,很明显第二个函数的第二部分与第一个函数很类似;
    这就是重构发挥作用的时候了,可以提高代码复用率;
    
    def polygon(t, length, n): # 画正n边形
    for i in range(n):
        t.fd(length)
        t.lt(360/n)
        
    def arc(t, r, angle):
    arc_length = 2 * pi * r * angle / 360
    n = int(arc_length / 3) + 1
    step_length = arc_length / n # 计算每一步要走的长度
    step_angle = angle / n # 计算每一步要走的角度
    
    for i in range(n):
        t.fd(step_length)
        t.lt(step_angle)
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

重构后,把相似的部分独立出来单独作为一个基础函数

复制代码
    def polyline(t, length, n, angle): # 基础函数
    for i in range(n):
        t.fd(length)
        t.lt(angle)
    
    def polygon(t, length, n): # 画正n边形
    polyline(t, length, n, 360/n)
    
    def arc(t, r, angle):
    arc_length = 2 * pi * r * angle / 360
    n = int(arc_length / 3) + 1
    step_length = arc_length / n # 计算每一步要走的长度
    step_angle = angle / n # 计算每一步要走的角度
    
    polyline(t, step_length, n, step_angle)
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

第五章

Python需要注意的运算符

1、乘方运算符:是“**”,而不是C语言等中的“^”。
2、向下取整除法操作符://,注意得到的数据类型不一定就是int形,也可能是25.0这样的float型。
3、求模操作符:%,即求余数。

条件链(chained conditional)

即有多种可能,需要多种判断条件 时,Python对于条件语法的结构如下:

复制代码
    其语法结构如下:
    if ...:
    ...
    elif ...:
    ...
    elif ...:
    ...
    else: # 可有可无
    ...
    
    
      
      
      
      
      
      
      
      
      
    

更便利的是,Python还支持C语法不支持的同时条件语法,比如:
如果变量x在3~10之间,就输出x,那么在C语言的写法一般是用and连接:

复制代码
    if (0<x and x<10)
    	print(x)
    
    
      
      
    

而在Python中,则允许直接用连续小于号:

复制代码
    if 0 < x < 10:
    	print(x)
    
    
      
      
    

递归(Recursion)

所谓的递归函数(Recursive Function),指的是自己调用自己的函数。虽然从直观上看递归很奇怪,但实际上它是程序所能做的最神奇的事情之一。关于递归的好处,在后面再说。
下面给出一个递归的例子:功能需求是打印输入的字符串n次

复制代码
    # 函数功能:打印输入的s字符串n次
    def print_n(s, n):
    if n<= 0:
        return
    print(s)
    print_n(s, n-1)
    
    print_n('abc', 3)
    
    
      
      
      
      
      
      
      
      
    

当然,对于这样简单的例子,使用for循环会更容易。但后面会发现有一些情况下,使用for循环很难写,但使用递归会更简单

无限递归

当递归函数没有设计退出机制时,就会陷入无限递归的情况。当然,在大多数程序环境中,无限递归的函数并不会真的永远执行,以Python举例,它会在递归深度达到上限时报告一个出错消息:

复制代码
    RuntimeError: Maximum recursion depth exceeded
    
    
      
    

键盘输入

Python提供了一个内置函数input从键盘获取输入 ,并等待用户输入一些东西 。用户的输入以回车键代表结束 ,程序会恢复运行,input字符串的形式 返回用户输入的内容。

复制代码
    text = input()
    print(text)
    
    
      
      
    

若输入what are you waiting for?,并按下回车后,则会在终端输出相同的字符串。
在这里插入图片描述
当然,我们通常希望从用户那里获得输入之前,能给用户一个提示信息,以告诉用户他们希望输入什么,在此,input函数可以接受一个字符串参数作为提示:

复制代码
    text = input('what...is your name?\n')
    print(text)
    
    
      
      
    

其结果如下,会先显示一行输入提示信息:
在这里插入图片描述
需要注意的是,一般提示信息最后会带上一个’\n’,这是为了让用户的输入显示在提示信息的下一行

第六章

isinstance()检查输入的类型

很多时候我们会要求函数的形参输入等必须为整数,这时候isinstance()就为我们提供了方便,其用法示例如下:

复制代码
    if isinstance(n, int): #如果n是整数,则执行后续语句
    	....
    
    
      
      
    

调试的思想

如果一个函数无法正常工作,那么我们在调试的时候应该考虑三种可能性:
(1)函数获得的实参有问题——打印输入看看;
(2)函数本身有问题——输出中间变量查看;
(3)函数的返回值有问题——输出中间变量查看;

第八章

搜索

搜索实际上就是遍历一个序列,当找到目标时返回。

in在字符串中的妙用

in实际上是一个布尔操作符,它可以操作于两个字符串上,如果第一个字符串被第二个完全包含,则返回True,否则返回False:

复制代码
    'a' in 'banana'
    >>>True
    
    
      
      
    

第十章:列表

sum在列表中的妙用

在Python中,对列表元素累加是如此常见的操作,以至于Python提供了一个内置函数sum()

复制代码
    t = [1,2,3]
    sum(t)
    >>>6
    
    
      
      
      
    

从列表中删除元素的方法

有三种方法:(1)如果知道要删除元素的下标,并且需要返回删除元素的值,可以使用pop()方法;(2)如果知道要删除元素的值,可以使用remove()方法;(3)如果知道要删除元素的下标,且不需要返回删除元素的值,可以用del方法,这也是比较常用的。

复制代码
    >>>t = ['a', 'b', 'c']
    >>>x = t.pop(1)
    >>>t
    ['b', 'c']
    >>>x
    'a'
    
    
      
      
      
      
      
      
    
复制代码
    >>>t = ['a', 'b', 'c']
    >>>t.remove('a')
    >>>t
    ['b', 'c']
    
    
      
      
      
      
    
复制代码
    >>>t = ['a', 'b', 'c']
    >>>del t[0:1]
    >>>t
    ['c']
    
    
      
      
      
      
    

列表和字符串

二者并不等同 。常用的转换函数是list(),将一个字符串转换成一个列表:

复制代码
    >>>s = 'spam'
    >>>t = list(s)
    >>>t
    ['s','p','a','m']
    
    
      
      
      
      
    

第十二章:字典

字典是Python最好的语言特性之一,它是很多算法的基本构建块。
字典类似于列表,但它更加通用。列表的下标为固定的整数,而字典的下标和值一样,几乎可以是任何类型,包括列表
字典的下标被称之为“键”,每个键都会和一个值相关,和列表一样。更专业地说,字典体现了键到值的映射

创建一个字典

两种方法:
第一种方法:通过dict()内置函数

复制代码
    eng = dict() # 创建一个空字典
    eng['one'] = 'uno' # 字典属于可变对象,可通过这种方式直接添加新项
    
    
      
      
    

第二种方法:直接用{}创建:

复制代码
    eng = {'one':'uno', 'two':'dos'}
    
    
      
    

需要注意的是,字典不同于列表,它是无序的,即如果你打印出一个字典,键值对的排列顺序很可能不会像你创建时一样

访问字典中的元素

上面已经提到,字典是无序的,所以它不能通过整数下标来访问。
相应的,字典通过键来查找对应的值:

复制代码
    >>>eng = {'one':'uno', 'two':'dos'}
    >>>eng['two']
    'dos'
    
    
      
      
      
    

len和in在字典中的应用

len在字典中返回的是键值对的数量:

复制代码
    >>>eng = {'one':'uno', 'two':'dos'}
    >>>len(eng)
    2
    
    
      
      
      
    

如何查看一个变量是否是字典的键或值

用in操作符判断一个变量是否是字典的键 ,它告诉你当前变量是否是字典中的 (注意这里是是否和键相同,而不是是否和值相同!)

复制代码
    >>>eng = {'one':'uno', 'two':'dos'}
    >>>'one' in eng
    True
    
    
      
      
      
    

通过values方法和in方法结合来判断变量是否是字典的值:values方法会返回字典的值集合:

复制代码
    >>>vals = eng.values() # 会返回一个值集合
    >>>'uno' in vals
    True
    
    
      
      
      
    

循环在字典中的应用

在for循环中使用字典,则会遍历字典的键,需要注意的是,键的出现同样没有特定的顺序:

复制代码
    >>> eng = {'o':'a', 'c':'b','n':'c'}
    >>> for i in eng: 
    >>>     print(i,eng[i])
    n c # 可以发现,并不是按定义的键的顺序输出的,而是按随机顺序遍历所有键
    o a
    c b
    
    
      
      
      
      
      
      
    

字典使用案例:作为计数器

给定一个字符串,计算每个字母出现的次数:

复制代码
    def count(str):
    d = {}
    for i in str: # 对字符串进行遍历,统计其每个元素
        if i in d: # 判断该字母是否在字典中,若在则其值加1
            d[i] = d[i] + 1
        elif i not in d: # 若不在则其值初始化为1
            d[i] = 1
    return d
    
    a = count('aabc')
    print(a)
    
    
      
      
      
      
      
      
      
      
      
      
      
    

输出结果为:

复制代码
    {'a': 2, 'c': 1, 'b': 1}
    
    
    
      
      
    

已知“值”,如何查找“键”

已知键的情况下,找到其对应的值是非常简单的。那么反过来呢,如果有值v,而想找到键k时怎么办?
这里一般会有两个问题:首先,可能存在多个键映射到同一个v值上,此时需要你自己决定是随机挑一个还是建立一个列表保存所有键;其次,并没有这种反向查找的简单语法,需要使用搜索实现。

复制代码
    def search(d,v): # 反向查找
    key = []
    for k in d: # 遍历字典 
        if d[k]==v: # 如果值对应上
            key.append(k)
    if key is None: # 如果没有任何值对应上,返回一个异常
        raise LookupError # 抛出一个异常
    else:
        return key
    
    d = {'a':1,'b':2,'c':3,'d':3}
    v = 3
    key = search(d,v)
    print(key)
    *********输出结果**********
    ['d', 'c']
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

元组

元组和列表的区别仅在于它是不可变 的,元组按照整数下标索引,其值也可以是任意类型。

创建一个元组

和列表、字典一样,用()即可创建:

复制代码
    >>> t1 = ('lupins', 'a', 'b')
    >>> print(t1)
    ('lupins', 'a', 'b')
    
    
      
      
      
    

但需要注意的是,若要新建一个只包含一个元素的元组需要在后面添加一个逗号而只用括号括起来的单独的值并不是元组

复制代码
    >>> t2 = ('lupins',) # 有逗号,返回的是一个元组
    ('lupins',) # 元组
    >>> t3 = ('lupins') # 无逗号,返回的是一个字符串,而不是元组
    lupins # 字符串
    
    
      
      
      
      
    

所以,这也是为什么常常看到(value,)这种只用一个元素元组会有一个额外的逗号的原因了。

访问元组中的元素

大多数列表操作都适用于元组:

复制代码
    >>> t = ('a','b','c') # 返回的是一个元组
    >>> print(t)
    ('a', 'b', 'c')
    >>> print(t[0]) # 访问单个元素
    a
    >>> print(t[1:3]) # 切片访问
    ('b', 'c')
    >>> for i in range(len(t)): # for循环遍历
    print(i, t[i])
    0 a
    1 b
    2 c
    >>> t[0] = 'd' # 元组是不可变的,不允许单个值的修改
    TypeError: 'tuple' object does not support item assignment
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

函数具有多个返回值时元组常常作为接受返回值的数据类型

复制代码
    >>>	def test(a, b):
    >>>	    return a,b
    >>>	c = test(1, 2) # 当用一个变量接受多个返回值时,这个变量会被赋予元组的数据类型
    >>>	print(type(c))
    <class 'tuple'>
    >>> e, f = test(1, 2)
    <class 'int'> <class 'int'>
    
    
      
      
      
      
      
      
      
    

用元组充当可变数量形参

函数可以接受不定个数的参数 ,以*开头的参数名会收集所有的参数到一个元组上,例如,下面的printall函数会接受任意个数的参数并打印它们:

复制代码
    >>> def printall(*args):
    >>>     print(args) 
    >>>     print(type(args)) # 把所有形参都收集到args元组上;
    >>> printall(1,'a','b')
    (1, 'a', 'b')
    <class 'tuple'>
    
    
      
      
      
      
      
      
    

很多内置函数都使用可变长参数元组,例如max和min都可以接收任意个数的参数:

复制代码
    >>> max(1,2,3,4)
    4
    
    
      
      
    

zip函数在元组中的应用

zip是一个常用的内置函数,它的名字取自于拉链(zipper)。和它的名字一样,它的意思就是将两行链牙交替连接 起来。具体来说,它的作用是接收两个或多个序列,并返回一个由各个序列的元素交替组成元组迭代器 ,代码示例如下,:

复制代码
    >>> s = 'abc'
    >>> t = [0,1,2]
    >>> zip(s,t)
    >>> print(zip)
    <zip object at 0x000001C6FCC7CA08> # 返回zip对象,它的本质是一种迭代器
    
    
      
      
      
      
      
    

使用zip对象最常用的方式是在for循环中,因为它是一个迭代器,着重理解“交替连接 ”,:

复制代码
    >>> s = 'abc'
    >>> t = [0,1,2]
    >>> a = zip(s,t)
    >>> for pair in a:
    >>>     print(pair)
    ('a', 0) # s的第一个元素和t的第一个元素构成第一个元组
    ('b', 1) # s的第二个元素和t的第二个元素构成第二个元组
    ('c', 2) #...
    
    
      
      
      
      
      
      
      
      
    

如果需要使用列表的操作符和方法,可以将zip对象制作成一个列表,这样也可以很清晰地看懂zip是如何进行交替连接成元组的

复制代码
    >>> s = 'abc'
    >>> t = [0,1,2]
    >>> a = list(zip(s,t))
    >>> print(a)
    [('a', 0), ('b', 1), ('c', 2)]
    
    
      
      
      
      
      
    

那么,如果两个序列长度不一致怎么办?按最短的那个来

复制代码
    >>> s = 'ab'
    >>> t = [0,1,2]
    >>> a = list(zip(s,t))
    >>> print(a)
    [('a', 0), ('b', 1)]
    
    
      
      
      
      
      
    

可以用for循环访问这种元组组成的列表

复制代码
    >>> t = [('a', 0), ('b',1),('c',2)]
    >>> for a, b in t:
    >>>     print(a, b)
    a 0
    b 1
    c 2
    
    
      
      
      
      
      
      
    

字典和元组

字典有一个item方法可以返回一个元组组成的迭代器,其中每个元组就是一个键值对:

复制代码
    >>> d = {'a':0,'b':1,'c':2}
    >>> t = d.items()
    >>> print(t)
    dict_items([('b', 1), ('c', 2), ('a', 0)])
    >>> for key, value in d.items(): # 由于字典是无序的,所以输出也是无序的
    >>>     print(key, value)
    b 1
    c 2
    a 0
    
    
      
      
      
      
      
      
      
      
      
    

同样地,可以使用一个元组列表来初始化一个新的字典:

复制代码
    >>> t = [('a',0),('c',2),('b',1)]
    >>> d = dict(t)
    >>> print(d)
    {'b': 1, 'a': 0, 'c': 2}
    
    
      
      
      
      
    

由此,组合dict和zip就可以得到一个简洁的创建字典的方法:

复制代码
    >>> d = dict(zip('abc', range(3)))
    >>> print(d)
    {'c': 2, 'b': 1, 'a': 0}
    
    
      
      
      
    

如何选择不同的数据结构

字符串相比其他序列有更明显的限制,因为它是不可变的,且元素必须是字符。如果你需要修改一个字符串中的字符,可能需要使用字符的列表。
列表比元组更加通用,因为它是可变的。但是在某些环境中可能需要用到元组,比如返回值、可变形参数等。

运算重载在列表、元组、字符串中的运用

包括+,*,>或<

复制代码
    >>> (0,1,2)<(0,3,4) # 按第一个不同元素的大小返回值
    True
    
    
      
      
    

用os模块操作文件

关于类,常见而又不熟悉的操作

__str__方法进行调试

当打印对象时,会输出__str__的返回值。

复制代码
    >>> class Test():
    >>>     def __str__(self):
    >>>         return 'abc'
    
    >>> test = Test()
    >>> print(test) # 打印对象
    abc
    
    
      
      
      
      
      
      
      
    

多态函数

能处理多个输入数据结构的函数称之为多态函数,比如下面的记录字母出现次数的函数能同时处理列表、元组、字典,那它就是多态的:

复制代码
    def histogram(s):
    d = dict()
    for c in s:
        if c not in d:
            d[c] = 1
        else:
            d[c] = d[c] + 1
    return d
    
    
      
      
      
      
      
      
      
      
    

全部评论 (0)

还没有任何评论哟~