《python可以这样学》第二章

Python序列

列表与列表推导式

列表创建与删除

创建列表对象

>>> a_list = list((3, 5, 7, 9, 11))
>>> a_list = []         #创建空列表

list()函数

将元组、range对象、字符串、字典、集合、或其他类型的可迭代对象类型的数据转换为列表

将元组转换为列表

>>> a_list = list((3, 5, 7, 9, 11))
>>> a_list
[3, 5, 7, 9, 11]

将range对象转换为列表

>>> list(range(1, 10, 2))
[1, 3, 5, 7, 9]

将字符串转换为列表

>>> list(‘hello world‘)
[‘h‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘, ‘ ‘, ‘w‘, ‘o‘, ‘r‘, ‘l‘, ‘d‘]

将集合转换为列表

>>> list({3, 7, 5})
[3, 5, 7]

将字典的“键”转换为列表

>>> list({‘a‘:3, ‘b‘:9, ‘c‘:78})
[‘a‘, ‘b‘, ‘c‘]

将字典的“键:值”对转换为列表

>>> list({‘a‘:3, ‘b‘:9, ‘c‘:78}.items())
[(‘a‘, 3), (‘b‘, 9), (‘c‘, 78)]

正向索引和反向索引

>>> x = list(range(10))       #创建列表
>>> import random
>>> random.shuffle(x)         #把列表中的元素打乱顺序
>>> x
[0, 7, 5, 9, 1, 2, 4, 8, 6, 3]
>>> x[0]
0
>>> x[1]
7
>>> x[-1]
3
>>> x[-2]
6

del命令删除列表、字典等可变序列中的部分元素,而不能删除元组、字符串等不可变序列中的部分元素

删除列表中指定位置的元素和列表对象

>>> x = [1, 2, 3]
>>> del x[1]
>>> x
[1, 3]
>>>
>>> del x
>>> x
Traceback (most recent call last):
  File "<pyshell#87>", line 1, in <module>
    x
NameError: name ‘x‘ is not defined

删除字典中部分元素

>>> x = {‘a‘:3, ‘b‘:6, ‘c‘:9}
>>> del x[‘a‘]
>>> x
{‘b‘: 6, ‘c‘: 9}

不允许删除和修改元组中的元素

>>> x = (1, 2, 3)
>>> del x[0]
Traceback (most recent call last):
  File "<pyshell#95>", line 1, in <module>
    del x[0]
TypeError: ‘tuple‘ object doesn‘t support item deletion
>>> x[0] = 4
Traceback (most recent call last):
  File "<pyshell#96>", line 1, in <module>
    x[0] = 4
TypeError: ‘tuple‘ object does not support item assignment

列表常用方法

1、append()、insert()、extend()

向列表尾部追加一个元素

append()

>>> x = [1, 2, 3]
>>> id(x)
46775496
>>> x.append(4)
>>> x
[1, 2, 3, 4]

任意指定位置插入一个元素

insert()

>>> x
[1, 2, 3, 4]
>>>
>>> x.insert(0, 0)
>>> x
[0, 1, 2, 3, 4]
>>> x.insert(3, 3.5)
>>> x
[0, 1, 2, 3.5, 3, 4]

将另一个列表中的所有元素追加至当前列表的尾部

extend()

在尾部追加多个元素

列表在内存中的地址不变

>>> x.extend([5, 6, 7])
>>> x
[0, 1, 2, 3.5, 3, 4, 5, 6, 7]
>>> id(x)
46775496

增加元素,返回新列表

>>> x = [1, 2, 3]
>>> id(x)
45846344
>>> x = x + [4]
>>> x
[1, 2, 3, 4]
>>> id(x)
46750984
>>> x = x * 2
>>> x
[1, 2, 3, 4, 1, 2, 3, 4]
>>> id(x)
46749064

2、pop()、remove()、clear()

删除并返回指定位置(默认是最后一个)上的元素

pop()

弹出并返回尾部元素

>>> x = [1, 2, 3, 4, 5, 6, 7]
>>> x.pop()
7

弹出并返回指定位置的元素(元素的下标已经发生改变)

>>> x.pop(0)
1
>>>
>>> x.pop(3)
5
>>>
>>> x.pop(1)
3
>>> x.pop(2)
6

删除所有元素

>>> x
[2, 4]
>>>
>>> x.clear()
>>>
>>> x
[]

删除列表中第一个值与指定值相等的元素

remove()

删除首个值为2的元素

>>> x = [1, 2, 1, 1, 2]
>>> x
[1, 2, 1, 1, 2]
>>> x.remove(2)
>>> x
[1, 1, 1, 2]

删除指定位置上的元素

>>> del x[3]
>>> x
[1, 1, 1]

3、count()、index()

返回列表中指定元素出现的次数

count()

>>> x = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
>>> x.count(3)
3
>>> x.count(5)
0

返回指定元素在列表中首次出现的位置,如果该元素不在列表中则抛出异常

>>> x.index(2)
1
>>> x.index(4)
6
>>> x.index(5)
Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    x.index(5)
ValueError: 5 is not in list
>>>
>>> 5 in x
False
>>> 3 in x
True
>>> 

4、sort()、reverse()

按照指定的规则对所有元素进行排序,默认规则是直接比较元素大小

sort()

随机乱序

>>> x = list(range(11))
>>> x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> import random
>>> random.shuffle(x)
>>> x
[0, 5, 1, 4, 9, 6, 8, 2, 10, 7, 3]

按指定规则排序

>>> x.sort(key = lambda item : len(str(item)), reverse = True)
>>> x
[10, 0, 5, 1, 4, 9, 6, 8, 2, 7, 3]

默认排序

>>> x.sort()
>>> x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

逆序

reverse()

>>> x.reverse()
>>> x
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

按转换为字符串后的大小排序

>>> x.sort(key = str)
>>> x
[0, 1, 10, 2, 3, 4, 5, 6, 7, 8, 9]

5、sorted()和reversed()

内置函数sorted()返回新列表,内置函数reversed()返回一个逆序排列后的迭代对象,都不对原列表做任何修改。

>>> x = list(range(11))
>>> import random
>>> random.shuffle(x)     #打乱顺序
>>> x
[3, 9, 1, 10, 5, 8, 6, 7, 2, 4, 0]
>>> sorted(x)                 #默认排序
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> sorted(x, key = lambda item : len(str(item)), reverse = True)         #以指定规则排序
[10, 3, 9, 1, 5, 8, 6, 7, 2, 4, 0]
>>> sorted(x, key = str)
[0, 1, 10, 2, 3, 4, 5, 6, 7, 8, 9]
>>> x
[3, 9, 1, 10, 5, 8, 6, 7, 2, 4, 0]
>>> reversed(x)                   #逆序
<list_reverseiterator object at 0x0000000002B1A630>
>>> list(reversed(x))
[0, 4, 2, 7, 6, 8, 5, 10, 1, 9, 3]

排序方法的key参数

>>> gameresult = [[‘bob‘, 95.0, ‘A‘], [‘alan‘, 86.0, ‘C‘], [‘mandy‘, 83.5, ‘A‘], [‘rob‘, 89.3, ‘E‘]]
>>> from operator import itemgetter

按子列表第三个元素进行升序排序

>>> sorted(gameresult, key=itemgetter(2))
[[‘bob‘, 95.0, ‘A‘], [‘mandy‘, 83.5, ‘A‘], [‘alan‘, 86.0, ‘C‘], [‘rob‘, 89.3, ‘E‘]]

按第三个元素升序,然后按第一个升序

>>> sorted(gameresult, key=itemgetter(2, 0))
[[‘bob‘, 95.0, ‘A‘], [‘mandy‘, 83.5, ‘A‘], [‘alan‘, 86.0, ‘C‘], [‘rob‘, 89.3, ‘E‘]]

……

>>> sorted(gameresult, key=itemgetter(2, 0), reverse = True)
[[‘rob‘, 89.3, ‘E‘], [‘alan‘, 86.0, ‘C‘], [‘mandy‘, 83.5, ‘A‘], [‘bob‘, 95.0, ‘A‘]]

以一个列表内容为依据,对另一个列表内容进行排序

>>> list1 = ["what", "I am", "sorting", "by"]
>>> list2 = ["something", "else", "to", "sort"]
>>> pairs = zip(list1, list2)       #把两个列表中的对应位置元素配对

……

>>> [item[1] for item in sorted(pairs, key=lambda x:x[0], reverse=True)]
[‘something‘, ‘to‘, ‘sort‘, ‘else‘]

把第二个元素升序、第三个元素降序排序

>>> x = [[1, 2, 3], [2, 1, 4], [2, 2, 1]]
>>> sorted(x, key=lambda item:(item[1], -item[2]))
[[2, 1, 4], [1, 2, 3], [2, 2, 1]]

先按长度排序,长度一样的正常排序

>>> x = [‘aaaa‘, ‘bc‘, ‘d‘, ‘b‘, ‘ba‘]
>>> sorted(x, key=lambda item:(len(item), item))
[‘b‘, ‘d‘, ‘ba‘, ‘bc‘, ‘aaaa‘]

内置函数对列表的操作

返回列表中所有元素的最大值和最小值

max()和min()

>>> x = list(range(11))
>>> import random
>>> random.shuffle(x)
>>> x
[7, 4, 2, 1, 10, 9, 6, 5, 8, 0, 3]
>>> max(x)
10
>>> max(x, key=str)
9
>>> min(x)
0

返回列表中所有元素之和

sum()

>>> sum(x)
55

返回列表中元素个数

len()

>>> len(x)
11

多列表元素重新组合

>>> list(zip(x, [1]*11))
[(7, 1), (4, 1), (2, 1), (1, 1), (10, 1), (9, 1), (6, 1), (5, 1), (8, 1), (0, 1), (3, 1)]

zip()函数也可以用于一个序列或迭代对象

>>> list(zip(range(1, 4)))
[(1,), (2,), (3,)]

如果两个列表不等长,以短的为准

>>> list(zip([‘a‘ ‘b‘, ‘c‘], [1, 2]))
[(‘ab‘, 1), (‘c‘, 2)]

枚举列表元素,返回enumerate对象

>>> x = list(range(11))
>>> import random
>>> random.shuffle(x)
>>> x
[6, 4, 3, 7, 1, 10, 9, 2, 5, 8, 0]
>>> enumerate(x)
<enumerate object at 0x0000000002C03CA8>
>>> list(enumerate(x))        #enumerate对象可迭代
[(0, 6), (1, 4), (2, 3), (3, 7), (4, 1), (5, 10), (6, 9), (7, 2), (8, 5), (9, 8), (10, 0)]
>>> 

map()

将一个函数依次作用(或映射)到序列或迭代器对象的每个元素上,并返回一个map对象作为结果

>>> list(map(str, range(5)))      #转换为字符串
[‘0‘, ‘1‘, ‘2‘, ‘3‘, ‘4‘]
>>> def add5(v):                  #单参数函数
    return v + 5

>>> list(map(add5, range(10)))    #把单参数函数映射到一个序列的所有元素
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>>
>>> def add(x, y):                #可以接受2个参数的函数
    return x + y

>>> list(map(add, range(5), range(5, 10)))     #把双参数函数映射到两个序列上[5, 7, 9, 11, 13]>>> list(map(lambda x, y:x+y, range(5), range(5, 10)))      [5, 7, 9, 11, 13]>>> [add(x, y) for x, y in zip(range(5), range(5, 10))][5, 7, 9, 11, 13]

reduce()

将一个接收2个参数的函数以累计的方式从左到右依次作用到一个序列或迭代器对象的所有元素上

>>> from functools import reduce
>>> seq = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> reduce(add, range(10))        #add是上一段代码中定义的函数
45
>>> reduce(lambda x, y:x+y, seq)  #使用lambda表达式实现相同功能
45

filter()

将一个单参数函数作用到一个序列上,返回该序列中使得该函数返回值为True的那些元素组成的filter对象,如果指定函数为None,则返回序列中等价与True的那些元素组成的filter对象,如果指定函数为None,则返回序列中等价于True的元素

>>> seq = [‘foo‘, ‘x41‘, ‘?!‘, ‘***‘]
>>> def func(x):
    return x.isalnum()                    #测试是否为字母或数字

>>> filter(func, seq)                     #返回filter对象
<filter object at 0x0000000002BB1390>
>>> list(filter(func, seq))               #把filter对象转换为列表
[‘foo‘, ‘x41‘]
>>> seq                                   #不对原列表做任何修改
[‘foo‘, ‘x41‘, ‘?!‘, ‘***‘]
>>> [x for x in seq if x.isalnum()]       #使用列表推导式实现相同功能
[‘foo‘, ‘x41‘]
>>> list(filter(lambda x:x.isalnum(), seq))         #使用lambda表达式实现相同功能
[‘foo‘, ‘x41‘]
>>> list(filter(None, [1, 2, 3, 0, 0, 4, 0, 5]))    #指定函数为None
[1, 2, 3, 4, 5]
>>> 

Python列表支持与整数的乘法运算,表示列表元素进行重复并生成新列表

>>> [1, 2, 3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]

列表之间的加法运算表示列表元素的合并,生成新列表

>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]

向量运算

生成10个[1, 100]区间内的随机数

>>> import random
>>> x = [random.randint(1, 100) for i in range(10)]
>>> x
[79, 86, 80, 51, 100, 37, 85, 94, 3, 23]

所有元素同时加5

>>> list(map(lambda i: i+5, x))
[84, 91, 85, 56, 105, 42, 90, 99, 8, 28]

向量内积

>>> x = [random.randint(1, 10) for i in range(10)]
>>> x
[9, 10, 2, 6, 5, 9, 8, 6, 4, 7]
>>> y = [random.randint(1, 10) for i in range(10)]
>>> y
[3, 1, 3, 2, 10, 8, 1, 10, 3, 9]
>>> import operator
>>> sum(map(operator.mul, x, y))
320

使用内置函数计算向量内积

>>> sum((i * j for i, j in zip(x, y)))
320

两个等长的向量对应元素相加

>>> list(map(operator.add, x, y))
[12, 11, 5, 8, 15, 17, 9, 16, 7, 16]

使用lambda表达式实现同样效果

>>> list(map(lambda i, j:i+j, x, y))
[12, 11, 5, 8, 15, 17, 9, 16, 7, 16]

列表推导式

语法:

[表达是 for 变量 in 序列或迭代对象]

列表推导式在逻辑上相当于一个循环,只是形式更加简洁

>>> aList = [x * x for x in range(10)]

相当于

>>> aList = []
>>> for x in range(10):
    aList.append(x * x)

也等价于

>>> aList = list(map(lambda x:x*x, range(10)))

再例如:

>>> freshfruit = [‘banana‘, ‘loganberry‘, ‘passion fruit‘]
>>> aList = [w.strip() for w in freshfruit]

等价于

>>> freshfruit = [‘banana‘, ‘loganberry‘, ‘passion fruit‘]
>>> aList = []
>>> for item in freshfruit:
    aList.append(item.strip())

也等价于

>>> freshfruit = [‘banana‘, ‘loganberry‘, ‘passion fruit‘]
>>> aList = list(map(lambda x:x.strip(), freshfruit))

>>> freshfruit = [‘banana‘, ‘loganberry‘, ‘passion fruit‘]
>>> aList = list(map(str.strip, freshfruit))

列表推导式强大功能

1、使用列表推导式实现嵌套列表的平铺

>>> 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]

等价于

>>> vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> result = []
>>> for elem in vec:
    for num in elem:
        result.append(num)

>>> result
[1, 2, 3, 4, 5, 6, 7, 8, 9]

2、过滤不符合条件的元素

列出当前文件夹下所有Python源文件

>>> import os
>>> [filename for filename in os.listdir(‘.‘) if filename.endswith(‘.py‘)]
[]

选择符合条件的元素组成新的列表

>>> aList = [-1, -4, 6, 7.5, -2.3, 9, -11]
>>> [i for i in aList if i > 0]      #所有大于0的数字
[6, 7.5, 9]

再例如,已知有一个包含一些同学成绩的字典,计算成绩的最高分、最低分、平均分,并查找所有最高分的同学

>>> scores = {"zhang san":45, "li si":78, "wang wu":40, "zhou liu":96, "zhao qi":65, "sun ba":90, "zheng jiu":78, "wu shi":99, "dong shiyi":60}
>>> highest = max(scores.values())       #最高分
>>> lowest = min(scores.values())        #最低分
>>> highest
99
>>> lowest
40
>>> average = sum(scores.values()) / len(scores)      #平均分
>>> average
72.33333333333333
>>> highestPerson = [name for name, score in scores.items() if score == highest]     #最高分所对应的名字
>>> highestPerson
[‘wu shi‘]

使用列表推导式查找列表中最大元素的位置

>>> from random import randint
>>> x = [randint(1, 10 ) for i in range(20)]
>>> m = max(x)
>>> m
10
>>> [index for index, value in enumerate(x) if value == m]         #输出最大值的下标位置
[11, 15, 16]
>>> x
[4, 4, 1, 9, 3, 1, 8, 2, 8, 7, 6, 10, 1, 1, 2, 10, 10, 9, 6, 6]

3、在列表推导式中使用多个循环,实现多序列元素的任意组合,并且可以结合条件语句过滤特定元素

>>> [(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)]

等价于

>>> result = []
>>> for x in [1, 2, 3]:
    for y in [3, 1, 4]:
        if x != y:
            result.append((x, y))

>>> result
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

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]]

或者,也可以使用内置函数zip()和list()来实现矩阵转置

>>> list(map(list, zip(*matrix)))                  #序列解包
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

或者

>>> matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
>>> result = []
>>> for i in range(len(matrix)):
    temp = []
    for row in matrix:
        temp.append(row[i])
        result.append(temp)

>>> result
[[1, 5, 9], [1, 5, 9], [1, 5, 9], [2, 6, 10], [2, 6, 10], [2, 6, 10], [3, 7, 11], [3, 7, 11], [3, 7, 11]]

5、列表推导式中可以使用函数或复杂表达式

>>> def f(v):
    if v%2 == 0:
        v = v**2
    else:
        v = v+1
    return v

>>> print([f(v) for v in [2, 3, 4, -1] if v>0])
[4, 4, 16]
>>> print([v**2 if v%2 == 0 else v+1 for v in [2, 3, 4, -1] if v>0])
[4, 4, 16]

6、列表推导式支持文件对象迭代

7、使用列表推导式生成100以内的所有素数

>>> [p for p in range(2, 100) if 0 not in [p%d for d in range(2, int(p**0.5)+1)]]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

切片

切片使用2个冒号分隔的3个数字来完成,第一个数字表示切片的开始位置(默认为0),第二个数字表示切片的截止(但不包含)位置(默认为列表长度),第三个数字表示切片的步长(默认为1),当步长省略时可以同时省略最后一个冒号

1、使用切片获取列表中的部分元素

返回包含原列表中所有元素的新列表

>>> [p for p in range(2, 100) if 0 not in [p%d for d in range(2, int(p**0.5)+1)]]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

返回包含原列表中所有元素的逆序列表

>>> 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:6]
[6, 7, 9]

切片的结束位置大于列表长度时,从列表尾部截断

>>> aList[0:100]
[3, 4, 5, 6, 7, 9, 11, 13, 15, 17]

切片的开始位置大于列表长度时,返回空列表

>>> aList[100:]
[]

不允许越界访问

>>> aList[100]
Traceback (most recent call last):
  File "<pyshell#39>", line 1, in <module>
    aList[100]
IndexError: list index out of range

2、切片对列表元素进行增、删、改

在列表尾部增加元素

>>> aList = [3, 5, 7]
>>> aList[len(aList):]
[]
>>> aList[len(aList):] = [9]
>>> aList
[3, 5, 7, 9]

替换列表元素

>>> aList
[3, 5, 7, 9]
>>>
>>> aList[:3] = [1, 2, 3]
>>> aList
[1, 2, 3, 9]

删除列表元素

>>> aList[:3] = []
>>> aList
[9]

替换列表元素

>>> aList = list(range(10))
>>> aList
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> aList[::2] = [0] * (len(aList) // 2)
>>> aList
[0, 1, 0, 3, 0, 5, 0, 7, 0, 9]

在列表指定位置插入元素

>>> aList
[0, 1, 0, 3, 0, 5, 0, 7, 0, 9]
>>>
>>> aList[3:3] = [4, 5, 6]
>>> aList
[0, 1, 0, 4, 5, 6, 3, 0, 5, 0, 7, 0, 9]
>>> len(aList)
13

在尾部追加元素,注意切片的范围

>>> aList
[0, 1, 0, 4, 5, 6, 3, 0, 5, 0, 7, 0, 9]
>>> aList[20:30] = [3] * 2
>>> aList
[0, 1, 0, 4, 5, 6, 3, 0, 5, 0, 7, 0, 9, 3, 3]

删除列表中的部分元素

>>> aList = [3, 5, 7, 9, 11]
>>> del aList[:3]
>>> aList
[9, 11]

注意:切片返回的是浅复制,与列表对象的直接赋值并不一样

>>> aList = [3, 5, 7]
>>> bList = aList          #指向同一个内存
>>> bList
[3, 5, 7]
>>> bList[1] = 8
>>> aList
[3, 8, 7]
>>> aList == bList        #两个列表的值是相等的
True
>>> aList is bList        #两个列表是同一个对象
True
>>> id(aList) == id(bList)    #两个列表是同一个内存地址
True

切片浅复制

>>> aList = [3, 5, 7]
>>> aList[::]
[3, 5, 7]
>>> bList = aList[::]
>>> aList == aList
True
>>>
>>> aList == bList
True
>>> aList is bList
False
>>> id(aList) is id(bList)
False
>>> id(aList[0]) == id(bList[0])
True
>>> bList[1] = 8
>>> bList
[3, 8, 7]
>>> aList
[3, 5, 7]
>>> aList == bList
False
>>> aList is bList
False

虽然直接把一个列表变量赋值给另一个变量时两个变量指向同一个内存地址,但是把一个列表分别赋值给2个变量时就不是这样的情况了

>>> x = [1, 2, 3]
>>> y = [1, 2, 3]
>>> id(x) == id(y)
False
>>> y.append(4)      #修改y的值,不影响x
>>> x
[1, 2, 3]
>>> y
[1, 2, 3, 4]

当列表中包含其他可变序列时,情况变得更加复杂

Python采用的是基于值的内存管理模式

Python变量中并不直接存放值,而是存放值的引用

>>> x = [[1], [2], [3]]
>>> y = x[:]
>>> y
[[1], [2], [3]]
>>> y[0] = [4]            #直接修改y中下标为0的元素值,不影响x
>>> y
[[4], [2], [3]]
>>> y[1].append(5)        #增加元素,影响x
>>> y
[[4], [2, 5], [3]]
>>> x
[[1], [2, 5], [3]]

使用切片修改列表元素值时,如果左侧切片是连续的,那么等号两侧的列表长度可以不一样;如果左侧切片不连续,则右侧列表中元素个数必须与左侧相等

使用del命令和切片删除列表中部分元素时,切片可以不连续

等号两侧不相等,抛出异常

>>> x = list(range(10))
>>> x[::2] = [3, 5]
Traceback (most recent call last):
  File "<pyshell#47>", line 1, in <module>
    x[::2] = [3, 5]
ValueError: attempt to assign sequence of size 2 to extended slice of size 5

等号两侧等长,可以执行

>>> x[::2] = [1, 1, 1, 1, 1]
>>> x
[1, 1, 1, 3, 1, 5, 1, 7, 1, 9]

删除列表中不连续的元素

>>> del x[::2]
>>> x
[1, 3, 5, 7, 9]

元组与生成器推导式

元组

元组的所有元素放在一对圆括号中,元素之间使用逗号分隔

元组赋值给一个变量

>>> x = (1, 2, 3)
>>> x
(1, 2, 3)
>>> type(x)
<class ‘tuple‘>
>>> x = (3)                #这和x = 3 是一样的
>>> x
3

如果元组中只有一个元素,必须在后面多写一个逗号

>>> x = (3, )
>>> x
(3,)

空元组

>>> x = ()
>>> x
()

将其他迭代对象转换为元组

>>> tuple(range(5))
(0, 1, 2, 3, 4)

元组属于不可变序列,无法为元组增加或删除元素。可以认为元组是轻量级的列表,或者“常量列表”

包含列表的元组,并修改元组中的列表

>>> x = ([1, 2], [3])
>>> x[0][0] = 5
>>> x
([5, 2], [3])
>>> x[0].append(8)            #为元组中的列表增加元素
>>> x
([5, 2, 8], [3])

生成器推导式

创建生成器对象

>>> g = ((i + 2) ** 2 for i in range(10))
>>> g
<generator object <genexpr> at 0x0000000002B82B88>

将生成器对象转换为元组

>>> tuple(g)
(4, 9, 16, 25, 36, 49, 64, 81, 100, 121)

生成器对象已遍历结束,没有元素了

>>> list(g)
[]

获取生成器对象的元素

__next__()

>>> g = ((i + 2) ** 2 for i in range(10))
>>> g.__next__()
4
>>> g.__next__()
9

获取下一个元素

>>> next(g)
16
>>> next(g)
25

使用循环直接遍历生成器对象中的元素

>>> 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 

使用生成器来生成斐波那契数列

>>> def f():                 #序列解包,同时为多个元素赋值
    a, b = 1, 1
    while True:
        yield a              #暂停执行,需要时再产生一个新元素
        a, b=b, a+b          #序列解包,继续生成新元素

>>> a = f()                  #创建生成器对象
>>> for i in range(10):      #斐波那契数列中前10个元素
    print(a.__next__(), end=‘ ‘)

1 1 2 3 5 8 13 21 34 55
>>> for i in f():            #斐波那契数列中第一个大于100的元素
    if i > 100:
        print(i, end=‘ ‘)
        break

144 

获取生成器对象中的元素,每次索取新元素时,有yield语句生成

>>> a = f()
>>> next(a)
1
>>> next(a)
1
>>> next(a)
2
>>> next(a)
3
>>> next(a)
5
>>> next(a)
8
>>> next(a)
13
>>> next(a)
21
>>> next(a)
34
>>> next(a)
55
>>> next(a)
89
>>> next(a)
144

字典

字典是包含若干“键:值”元素的无序可变序列

创建一个字典变量

>>> a_dict = {‘server‘:‘db.diveintopython3.prg‘, ‘database‘:‘mysql‘}
>>> a_dict
{‘server‘: ‘db.diveintopython3.prg‘, ‘database‘: ‘mysql‘}

使用内置函数快速创建字典

dict()

>>> keys = [‘a‘, ‘b‘, ‘c‘, ‘d‘]
>>> values = [1, 2, 3, 4]
>>> dictionary = dict(zip(keys, values))
>>> print(dictionary)
{‘a‘: 1, ‘b‘: 2, ‘c‘: 3, ‘d‘: 4}

创建空字典

>>> x = dict()
>>> x
{}
>>> type(x)
<class ‘dict‘>

给定键和值来创建字典

>>> d = dict(name=‘djl‘, age=23)
>>> d
{‘name‘: ‘djl‘, ‘age‘: 23}

创建值为空的字典

>>> adict = dict.fromkeys([‘name‘, ‘age‘, ‘sex‘])
>>> adict
{‘name‘: None, ‘age‘: None, ‘sex‘: None}

当以指定“键”为下标为字典元素赋值时,有两种含义:

1、若该“键”存在,则表示修改该“键”对应的值

2、若该“键”不存在,则表示添加一个新的“键:值”

例如:

修改元素值

>>> aDict = dict(name=‘djl‘, age=‘23‘, sex=‘male‘)
>>> aDict
{‘name‘: ‘djl‘, ‘age‘: ‘23‘, ‘sex‘: ‘male‘}
>>> aDict[‘age‘] = 25
>>> aDict
{‘name‘: ‘djl‘, ‘age‘: 25, ‘sex‘: ‘male‘}

添加新元素

>>> aDict
{‘name‘: ‘djl‘, ‘age‘: 25, ‘sex‘: ‘male‘}
>>> aDict[‘address‘] = ‘shandong‘
>>> aDict
{‘name‘: ‘djl‘, ‘age‘: 25, ‘sex‘: ‘male‘, ‘address‘: ‘shandong‘}

返回所有元素

>>> aDict = dict(name=‘djl‘, score=‘[98, 97]‘, age=‘23‘, sex=‘male‘)
>>> aDict
{‘name‘: ‘djl‘, ‘score‘: ‘[98, 97]‘, ‘age‘: ‘23‘, ‘sex‘: ‘male‘}
>>> aDict.items()
dict_items([(‘name‘, ‘djl‘), (‘score‘, ‘[98, 97]‘), (‘age‘, ‘23‘), (‘sex‘, ‘male‘)])

修改“age”键的值,同时添加新元素‘a‘:97

update()方法

将另一个字典的“键:值”一次性全部添加到当前字典对象,如果两个字典中存在相同的“键,则以另一个字典中的“值”为准对当前字典进行更新

>>> aDict.update({‘a‘:97, ‘age‘:39})
>>> aDict
{‘name‘: ‘djl‘, ‘score‘: ‘[98, 97]‘, ‘age‘: 39, ‘sex‘: ‘male‘, ‘a‘: 97}

删除字典元素

>>> aDict
{‘name‘: ‘djl‘, ‘score‘: ‘[98, 97]‘, ‘age‘: 39, ‘sex‘: ‘male‘, ‘a‘: 97}
>>> del aDict[‘age‘]
>>> aDict
{‘name‘: ‘djl‘, ‘score‘: ‘[98, 97]‘, ‘sex‘: ‘male‘, ‘a‘: 97}

删除整个字典

>>> aDict
{‘name‘: ‘djl‘, ‘score‘: ‘[98, 97]‘, ‘sex‘: ‘male‘, ‘a‘: 97}
>>>
>>> del aDict
>>> aDict           #字典对象被删除后不再存在
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    aDict
NameError: name ‘aDict‘ is not defined

弹出一个元素(对空字典会抛出异常)

popitem()

>>> aDict = dict(age=‘23‘, score=‘[98, 97]‘, name=‘djl‘, sex=‘male‘)
>>> aDict
{‘age‘: ‘23‘, ‘score‘: ‘[98, 97]‘, ‘name‘: ‘djl‘, ‘sex‘: ‘male‘}
>>> aDict.popitem()
(‘sex‘, ‘male‘)
>>> aDict
{‘age‘: ‘23‘, ‘score‘: ‘[98, 97]‘, ‘name‘: ‘djl‘}

弹出指定键对应的元素

>>> aDict
{‘age‘: ‘23‘, ‘score‘: ‘[98, 97]‘, ‘name‘: ‘djl‘}
>>> aDict.pop(‘name‘)
‘djl‘
>>> aDict
{‘age‘: ‘23‘, ‘score‘: ‘[98, 97]‘}

访问字典对象的数据

指定的“键”存在,返回对应的“值”

>>> aDict = {‘age‘:23, ‘score‘:[98, 97], ‘name‘:‘djl‘, ‘sex‘:‘male‘}
>>> aDict
{‘age‘: 23, ‘score‘: [98, 97], ‘name‘: ‘djl‘, ‘sex‘: ‘male‘}
>>> aDict[‘age‘]
23
>>> aDict
{‘age‘: 23, ‘score‘: [98, 97], ‘name‘: ‘djl‘, ‘sex‘: ‘male‘}

指定的“键”不存在,抛出异常

>>> aDict[‘address‘]
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    aDict[‘address‘]
KeyError: ‘address‘

get()方法

用来返回指定“键”对应的“值”,允许指定该键不存在

>>> aDict.get(‘age‘)
23
>>> aDict.get(‘address‘)
>>> aDict
{‘age‘: 23, ‘score‘: [98, 97], ‘name‘: ‘djl‘, ‘sex‘: ‘male‘}
>>>
>>> aDict.get(‘address‘, ‘Not Exists‘)
‘Not Exists‘

增加新元素

setdefault()方法

返回指定“键”对应的“值”,如果字典中不存在该“键”,就添加一个新元素并设置键值对

>>> aDict.setdefault(‘address‘, ‘shandong‘)
‘shandong‘
>>> aDict
{‘age‘: 23, ‘score‘: [98, 97], ‘name‘: ‘djl‘, ‘sex‘: ‘male‘, ‘address‘: ‘shandong‘}

遍历字典中所有的“键”

>>> aDict
{‘age‘: 23, ‘score‘: [98, 97], ‘name‘: ‘djl‘, ‘sex‘: ‘male‘, ‘address‘: ‘shandong‘}
>>> for item in aDict:
    print(item)

age
score
name
sex
address

明确指定遍历字典的所有元素

>>> for item in aDict.items():
    print(item)

(‘age‘, 23)
(‘score‘, [98, 97])
(‘name‘, ‘djl‘)
(‘sex‘, ‘male‘)
(‘address‘, ‘shandong‘)
>>> aDict.items()
dict_items([(‘age‘, 23), (‘score‘, [98, 97]), (‘name‘, ‘djl‘), (‘sex‘, ‘male‘), (‘address‘, ‘shandong‘)])

遍历字典的所有键

>>> aDict.keys()
dict_keys([‘age‘, ‘score‘, ‘name‘, ‘sex‘, ‘address‘])

遍历字典的所有值

>>> aDict.values()
dict_values([23, [98, 97], ‘djl‘, ‘male‘, ‘shandong‘])

有序字典

Python内置字典是无序的

>>> import collections
>>> x = collections.OrderedDict()
>>> x[‘a‘] = 3
>>> x[‘b‘] = 5
>>> x[‘x‘] = 8
>>> x
OrderedDict([(‘a‘, 3), (‘b‘, 5), (‘x‘, 8)])

对字典元素进行排序并返回新列表

sorted()

按字典的“值”进行排序

>>> 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‘)]
>>> sorted(phonebook.items(), key=lambda item:item[0])
[(‘bob‘, ‘9345‘), (‘carol‘, ‘5834‘), (‘linda‘, ‘7750‘)]

使用key来指定排序依据,先按姓名升序排序,姓名相同的按年龄降序排序

>>> persons = [{‘name‘:‘dong‘, ‘age‘:37},
       {‘name‘:‘Li‘, ‘age‘:40},
       {‘name‘:‘zhang‘, ‘age‘:30},
       {‘name‘:‘du‘, ‘age‘:23},
       {‘name‘:‘Li‘, ‘age‘:25}]
>>> print(persons)
[{‘name‘: ‘dong‘, ‘age‘: 37}, {‘name‘: ‘Li‘, ‘age‘: 40}, {‘name‘: ‘zhang‘, ‘age‘: 30}, {‘name‘: ‘du‘, ‘age‘: 23}, {‘name‘: ‘Li‘, ‘age‘: 25}]
>>> print(sorted(persons, key=lambda x:(x[‘name‘], -x[‘age‘])))
[{‘name‘: ‘Li‘, ‘age‘: 40}, {‘name‘: ‘Li‘, ‘age‘: 25}, {‘name‘: ‘dong‘, ‘age‘: 37}, {‘name‘: ‘du‘, ‘age‘: 23}, {‘name‘: ‘zhang‘, ‘age‘: 30}]

字典推导式快速生成符合特定条件的字典

>>> {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‘, ‘c‘, ‘d‘]
>>> {i:j for i, j in zip(x, y)}
{‘A‘: ‘a‘, ‘B‘: ‘b‘, ‘C‘: ‘c‘, ‘D‘: ‘d‘}

集合

集合是无序可变序列,使用一对大括号作为界定符,元素之间使用逗号分隔,同一个集合内的每个元素都是唯一的,元素之间不允许重复

创建集合对象

>>> a = {3, 5}
>>> a
{3, 5}
>>> type(a)
<class ‘set‘>

将列表、元组等其他可迭代对象转换为集合

set()函数

把range对象转换为集合

>>> a_set = set(range(8, 14))
>>> a_set
{8, 9, 10, 11, 12, 13}

把列表转换为集合,自动去掉重复元素

>>> b_set = set([0, 1, 2, 3, 4, 0, 1, 2, 3, 7, 8])
>>> b_set
{0, 1, 2, 3, 4, 7, 8}

空集合

>>> x = {}
>>> x
{}
>>> x = set()
>>> x
set()

集合中只能包含数字、字符串、元组等不可变类型(或者说可哈希)的数据,而不能包含列表、字典、集合等可变类型的数据

集合操作与运算

1、集合元素增加与删除

添加、更新元素,重复元素自动忽略

add()

update()

>>> s = {1, 2, 3}
>>> s.add(3)
>>> s
{1, 2, 3}
>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> s.update({3, 4, 5})
>>> s
{1, 2, 3, 4, 5}

从集合中删除一个特定元素,如果元素不存在则忽略该操作

discard()

>>> s
{1, 2, 3, 4, 5}
>>>
>>> s.discard(5)
>>> s
{1, 2, 3, 4}
>>> s.discard(7)
>>> s
{1, 2, 3, 4}

删除集合中的元素,如果指定元素不存在则抛出异常

>>> s
{1, 2, 3, 4}
>>>
>>> s.remove(3)
>>> s
{1, 2, 4}
>>> s.remove(5)
Traceback (most recent call last):
  File "<pyshell#155>", line 1, in <module>
    s.remove(5)
KeyError: 5

随机删除并返回集合中的一个元素,如果集合为空则抛出异常

>>> s
{1, 2, 4}
>>> s.pop()
1
>>> s
{2, 4}

2、集合运算

并集

union()

>>> 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.union(b_set)
{0, 1, 2, 3, 7, 8, 9, 10, 11, 12, 13}

交集

intersection()

>>> a_set & b_set
{8}
>>> a_set.intersection(b_set)
{8}

差集

difference()

>>> a_set - b_set
{9, 10, 11, 12, 13}
>>> a_set.difference(b_set)
{9, 10, 11, 12, 13}

对称差集

symmetric_difference()

>>> a_set ^ b_set
{0, 1, 2, 3, 7, 9, 10, 11, 12, 13}
>>> a_set.symmetric_difference(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

测试是否为子集

issubset()

>>> x.issubset(y)
False
>>> x.issubset(z)
True

自定义枚举类型

>>> from enum import Enum
>>> class Color(Enum):        #创建自定义枚举类
    red = 1
    blue = 2
    green = 3

>>> Color.red            #访问枚举的成员
<Color.red: 1>
>>> type(Color.green)    #差可能枚举成员的类型
<enum ‘Color‘>
>>> isinstance(Color.red, Color)
True
>>> x = dict()
>>> x[Color.red] = ‘red‘      #枚举成员可哈希,可作为字典的“键”
>>> x
{<Color.red: 1>: ‘red‘}
>>> Color(2)             #返回指定值对应的枚举类成员
<Color.blue: 2>
>>> Color[‘red‘]
<Color.red: 1>
>>> r = Color.red
>>> r.name
‘red‘
>>> r.value
1
>>> list(Color)             #枚举类是可以迭代的
[<Color.red: 1>, <Color.blue: 2>, <Color.green: 3>]

直接从指定序列中选取指定数量个不重复的元素

sample()

>>> import random
>>> random.sample(range(1000), 20)
[334, 827, 678, 299, 174, 296, 610, 886, 156, 5, 668, 657, 335, 83, 105, 602, 481, 384, 116, 764]

集合推导式

>>> {x.strip() for x in (‘he‘, ‘she‘, ‘I‘)}
{‘I‘, ‘she‘, ‘he‘}
>>> import random
>>> x = {random.randint(1, 500) for i in range(100)}     #生成随机数,自动去除重复元素
>>> x
{4, 13, 26, 32, 39, 45, 66, 76, 80, 85, 86, 88, 91, 94, 102, 114, 115, 119, 120, 121, 129, 131, 156, 157, 162, 164, 173, 185, 192, 198, 211, 214, 220, 226, 236, 240, 249, 252, 254, 256, 259, 271, 286, 293, 294, 295, 296, 297, 301, 325, 330, 331, 332, 334, 336, 346, 347, 354, 358, 363, 372, 383, 390, 393, 394, 423, 428, 435, 436, 438, 444, 450, 458, 467, 468, 469, 471, 474, 477, 482, 489, 490, 493, 495}
>>>
>>> len(x)
84
>>>
>>> {str(x) for x in range(10)}
{‘5‘, ‘1‘, ‘2‘, ‘9‘, ‘8‘, ‘0‘, ‘4‘, ‘7‘, ‘6‘, ‘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 = map(str, range(3))     #使用迭代对象进行序列解包

列表与字典的序列解包

>>> a = [1, 2, 3]
>>> b, c, d=a             #列表也支持序列解包的用法
>>> b
1
>>> x, y, z=sorted([1, 3, 2])       #sorted()函数返回排序后的列表
>>> s = {‘a‘:1, ‘b‘:2, ‘c‘:3}
>>> b, c, d=s.items()
>>> b                    #这里的结果如果和你的不一样是正常的
(‘a‘, 1)
>>> b, c, d=s            #使用字典时不用考虑元素的顺序
>>> b                    #多执行几次试试,或许结果会有变化
‘a‘
>>> b, c, d=s.values()
>>> print(b, c, d)
1 2 3

使用序列解包可以很方便地同时遍历多个序列

>>> keys = [‘a‘, ‘b‘, ‘c‘, ‘d‘]
>>> values = [1, 2, 3, 4]
>>> for k, v in zip(keys, values):
    print(k, v)

a 1
b 2
c 3
d 4

内置函数enumerate()返回的迭代对象进行遍历时序列解包的用法

>>> x = [‘a‘, ‘b‘, ‘c‘]
>>> for i, v in enumerate(x):
    print(‘The value on position {0} is {1}‘.format(i, v))

The value on position 0 is a
The value on position 1 is b
The value on position 2 is c

字典中的序列解包

>>> s = {‘a‘:1, ‘b‘:2, ‘c‘:3}
>>> for k, v in s.items():
    print(k, v)

a 1
b 2
c 3

序列解包还支持下面的用法

>>> 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}}
{‘x‘: 1, ‘y‘: 2}

在实参前面加上一个星号(*)也可以进行序列解包,从而实现将序列中的元素值依次传递给相同数量的形参

原文地址:https://www.cnblogs.com/djlsunshine/p/10857582.html

时间: 2024-10-27 00:28:01

《python可以这样学》第二章的相关文章

大道至简第二章—懒人的方法

大道至简第二章—懒人的方法 僰道有故蜀王兵阑亦有神,作大滩江中.其崖崭峻,不可凿:乃积薪烧之.故其处悬崖有赤白五色. ----华阳国志卷三-蜀志 在第一章中作者引用愚公移山的典故向我们介绍了编程的精义,以愚公为例向我们介绍了个编程人员应具备的素质.而在第二章,作者通过蜀郡太守李冰烧石破山建造都江堰的故事告诉我们我们只是勤奋是不够的.如果李冰像愚公那样日复一日的敲石碎山,就不会有空闲时间去观察,去思考了.那也不会有“积薪烧之”的事情了.所以李冰乃是闲人一枚. 人的精力是有限的.愚公而愚公可以多吃点

读大道至简第二章有感

大道至简第二章的题目是"是懒人造就了方法"而开头也写到李冰的开山并与愚公移山做了比较,无非就是想用具体的例子来证明懒人造就方法的观点.而其深层的含义便是要学会观察,学会思考,同样是一件事,很多人都能做,有人用的时间长资源多,而有的人则截然相反,这就说明了观察思考的重要性,而相对于编程来说,一个简单的比较大小的问题,有的人比较五次,而有的人只比较四次就能运行出结果,这就是程序的优化,也是思考的结果 一百万行代码是可以写在一个文件里的.这反映了一个很常见的问题,很多初学者比如我们总是在关注

大道至简第二章读后感

 读了大道至简第一章的老愚公的故事,我们知道了勤劳的人总会能够完成所有的困难,最终完成自己的任务,完成自己的目标,愚公移山,看似不能完成,但是与共凭借着子又生孙,孙又生子,活生生的完成了这一个不可能完成的任务,但是在旁人眼里看来,又有一些古板,耗时,毕竟动用了不知道多少代子孙的时间,反而观之第二章的李冰,修建都江堰,也需要“移山”,而且山上又全是石头,要是按照愚公的办法,那得修到什么时候才能完工?但是他发现了最终的方法,用火烧石头,然后浇水,石头就会变得酥脆容易挖走,这就是一种智慧. 从某种情况

读《大道至简-第二章》有感

在生活中,“懒惰”常常被人讥笑,“懒人”更是不受欢迎.而劝人勤奋的名言典故却数不胜数,  什么“业精于勤,荒于嬉”,“书山有路勤为径,学海无涯苦作舟”.“三更灯火五更鸡,正是男儿读书时”.更有“头悬梁,锥刺股”等等.人们以勤为荣,以苦为乐.但当我读完<大道至简>的第二章后,我对“懒惰”有了新的认识. 这一章别出心裁的将“愚公移山”和“李冰凿离堆”的故事放在一起进行对比.文中的“懒惰”是指那些讨厌吃苦受累,懒于无效劳动,不愿因循守旧,但是却积极开动脑筋,不断创新,想出省时省力的懒办法,他们是聪明

大道至简第二章观后感

大道至简读后感 第二章的标题是懒人造就了方法.也就是说只有懒的人才有时间和精力去想出各种可以提高做事效率,即事半功倍的方法.在文章中作者所提到的<华阳国志>里所写的李冰,我们可以肯定他不是一个很勤快的人,就像愚公,如果他是一个勤快的人,那么他肯定也是和愚公一样扣石垦壤,自然而然,他也就不会,也没有精力去发现“积薪烧山”的方法了.很显然,勤快的人有勤快人的方法——凿石开山,相应的懒人也自有懒人的方法——积薪烧山.这说明懒人比勤快人有更多的时间去思考,观察,进而发现一些捷径.人的精力终究是有限的,

《大道至简第二章》读后感

在第一章我们学到了编程的精义,引用了古代愚公的故事,而在第二章,作者又引用了李冰凿山的故事为我们揭示了这章的主题,“是懒人造就了方法”. 应该说我非常喜欢作者的这个观点吧,因为我也是懒人一族,每当朋友.家人说我真是懒得时候,我总是骄傲的说“世界是懒人创造的哦,不要看不起懒人”.当时虽然是说笑的,但是心里很认同.就拿愚公.李冰这事来说,目的同样是凿山,但是愚公直接是“碎石击壤”,率着家人世世代代凿山,没有经过任何分析,换句话说愚公太勤奋了,所以即使力量微不足道,还是可以世世代代传承凿山这件事,并且

大道至简-第二章 心得体会

大道至简——是懒人造就了方法    心得体会 “ 僰道有蜀王兵蘭,亦有神作大潭江中.其崖崭峻不可破,(冰)乃积薪烧之.” ——<华阳国志> 从这段历史文献中我们可以看到,李冰同样是凿山但是他懂得方法,懂得怎样快速的破山凿山.这大概就是愚公和李冰的区别了(李冰是‘积薪烧之’而愚公是‘碎石击壤’)这两种方法的结果差距是很大的. 很明显李冰的方法更高级一点,那么问题来了,李冰为什么会找到这种方法而愚公没有找到呢?如果李冰也和愚公一样每天都忙东忙西“受命以来,夙夜忧叹”每天连吃饭的时间都没有,那他可以

《大道至简第二章读后感》

第二章开篇将愚公与李冰作比较,愚公只知道日复一日,年复一年地挖山,毋庸置疑,他是个勤奋的人,然而,他的勤奋让他没有时间来找寻一个更方便快捷的方法,相比之下,李冰用懒人的方法凿了一座山,用时比愚公少,人力资源消耗小,同是战国时期,愚公就要碎石击壤,而李冰已经懂得积薪烧之了,换句话说,是懒人造就了方法. 李冰积薪烧之的方法来由一次闲极无聊的给夫人烧饭,发现垒灶的鹅卵石被烧的爆裂开来,遇水于甚,所以说人的精力是有限的,提出新的方法,解决的将是影响做事成效的根本问题.早期的程序是将代码打在穿孔纸上让计算

李冰烧山——大道至简第二章读后感

读了第一章的愚公移山,让我更深刻的体会到了编程的精义,就是把一个复杂的问题分解成一个个小问题,逐个解决.就像编写一个最大公约数,就要先想出两个数的最小公倍数,而最小公倍数的求法,就可以用1开始一直除到这个数的一半,然后再找出能除尽的最大的数.这样,一个问题就被我们分解开,快速的解决. 而第二章,主人公变成了李冰.战国时期的李冰凿了一座山,他的方法和愚公有着天壤之别,愚公会凿,李冰会烧.在两千年前的某一天,闲极无聊的李冰下厨给夫人炒了一个小菜,他突然发现垒灶的鹅卵石被烧得爆裂开来,遇水尤甚.从此<

续--大道至简第二章

简直了,这一章的内容就很直白了,懒人嘛,大家同属一类,但这个“懒”也是划分了一个界线.李冰建造都江堰,工程更加浩大,然而却是比愚公移山轻松多了.烧山和挖山的精要就在于“懒”的方法,只有勤于动脑筋才能让本来繁琐的工作有径可循,而且还能很大程度上提高工作效率,这永远是管理者想要看到的.而对于愚公这样的人,只能说他是属于勤快且踏实的人,老黄牛的类型,我想创新型的人才更加受欢迎罢了. 然而人的精力总是有限的,你想等着世世代代无穷,那时代就早已经把你丢在了后方了,毕竟长江后浪推前浪,很容易被后浪拍在沙滩上