AUTOMATE THE BORING STUFF WITH PYTHON读书笔记 - 第4章:LISTS

LIST数据类型

list用[]定义,其中的值称为item,用逗号分割。例如[1, 2, 3]
空的列表用[]定义。第一个值的序号为0,最后一个值的序号为-1。
list中的item可以是list:

>>> list1 = [1, 2, 3]
>>> list1[0]
1
>>> list2 = [ [1,2], [2,3]]
>>> list2[0]
[1, 2]
>>> list2[0][1]
2

可以指定开始和结束值获取list的片段,开始值如省略则为0,结束值如省略则为-1:

>>> list1 = [1, 2, 3]
>>> list1[0:2]
[1, 2]
>>> list1[0:]
[1, 2, 3]
>>> list1[:3]
[1, 2, 3]
>>> list1[:]
[1, 2, 3]

list的长度可用len()获取:

>>> list1 = [1, 2, 3]
>>> len(list1)
3

list中的成员可以直接赋值:

list1[0] = 5

两个list可以用+号拼接:

>>> list1 = [1, 2, 3]
>>> list2 = [3, 4, 5]
>>> list1 + list2
[1, 2, 3, 3, 4, 5]
>>> list1 = [1, 2, 3]
>>> list1 + [4]
[1, 2, 3, 4]

和字符串一样,list的复制也是用*号:

>>> 'str' * 3
'strstrstr'
>>> [1, 2] * 3
[1, 2, 1, 2, 1, 2]

删除list的成员用del

>>> list1
[1, 2, 3]
>>> del list1[0]
>>> list1
[2, 3]

操作List

range()返回的是序列,类似于list:

>>> for i in range(4):
...     print(i)
... 
0
1
2
3

list与range的结合:

>>> supplies = ['pens', 'staplers', 'flamethrowers', 'binders']
>>> for i in range(len(supplies)):
...     print('Index ' + str(i) + ' in supplies is: ' + supplies[i])
... 
Index 0 in supplies is: pens
Index 1 in supplies is: staplers
Index 2 in supplies is: flamethrowers
Index 3 in supplies is: binders

判断某值是否在list中,可用innot in

>>> 1 in [1, 2]
True
>>> 3 in [1, 2]
False
>>> 3 not in [1, 2]
True

多变量赋值也称为tuple unpacking,例如:

>>> cat = ['fat', 'gray', 'loud']
>>> size, color, disposition = cat
>>> size
'fat'
>>> color
'gray'

enumerate和list结合时,返回两个值,一个是序号,一个是值。例如:

>>> supplies = ['pens', 'staplers', 'flamethrowers', 'binders']
>>> for index, item in enumerate(supplies):
...     print('Index ' + str(index) + ' in supplies is: ' + item)
... 
Index 0 in supplies is: pens
Index 1 in supplies is: staplers
Index 2 in supplies is: flamethrowers
Index 3 in supplies is: binders

random.choice可以随机返回list中的值,random.shuffle可以重组list中的值,类似于洗牌。

>>> import random
>>> people = ['Alice', 'Bob', 'Carol', 'David']
>>> random.choice(people)
'David'
>>> random.choice(people)
'Alice'
>>> random.shuffle(people)
>>> people
['Alice', 'Carol', 'Bob', 'David']
>>> random.shuffle(people)
>>> people
['David', 'Bob', 'Carol', 'Alice']

扩展赋值符

augmented assignment operator也称为扩展赋值符。包括+=, -=, *=, /=%=
例如:

>>> a = 1
>>> a += 1
>>> a
2

方法

方法,也称为mothod,和函数类似,区别在于需要通过一个值来调用。
每一个数据类型都有自己的方法。

>>> l1 = [1, 2, 3, 3, 2, 1]
# 返回第一个匹配值的索引
>>> l1.index(3)
2
>>> l1.append(4)
>>> l1
[1, 2, 3, 3, 2, 1, 4]
>>> l1.insert(2, 5)
>>> l1
[1, 2, 5, 3, 3, 2, 1, 4]
# 删除第一个匹配的值
>>> l1.remove(3)
>>> l1
[1, 2, 5, 3, 2, 1, 4]
>>> l1.sort()
>>> l1
[1, 1, 2, 2, 3, 4, 5]
>>> l1.sort(reverse=True)
>>> l1
[5, 4, 3, 2, 2, 1, 1]
>>> l2 = ['C', 'B', 'A', 'a', 'c', 'b']
>>> l2.sort()
>>> l2
['A', 'B', 'C', 'a', 'b', 'c']
>>> l2.sort(key=str.lower)
>>> l2
['A', 'a', 'B', 'b', 'C', 'c']
>>> l1.reverse()
>>> l1
[1, 1, 2, 2, 3, 4, 5]

list赋值可以跨行,此外,类似于C语言,在行尾指定\也可以跨行:

>>> a = [1, 2
... ,3]
>>> a
[1, 2, 3]

>>> a = 1 + \
... 2
>>> a
3

示例程序: 使用LIST实现MAGIC 8 BALL

从8个球中选一个:

import random

messages = ['It is certain',
    'It is decidedly so',
    'Yes definitely',
    'Reply hazy try again',
    'Ask again later',
    'Concentrate and ask again',
    'My reply is no',
    'Outlook not so good',
    'Very doubtful']

print(messages[random.randint(0, len(messages) - 1)]) 
# 或者
print(random.choice(messages))

SEQUENCE 数据类型

list属于sequence数据类型,其它属于此类型的包括字符串,range()的返回值以及tuple。
sequence类型的共同特征包括可以索引,可以切片,可以用在for...in循环,可以用len求长度。
例如对于字符串类型:

>>> name = 'Steven'
>>> name[0]
'S'
>>> 'S' in name
True
>>> len(name)
6
>>> 'even' in name
True
>>> for c in name:
...     print(c)
... 
S
t
e
v
e
n

但字符串和list的区别在于,list是可变(mutable)的,可以修改,增删item。而字符串是不可变(immutable)的。
不过,如果需要,还是可以用切片和拼接手段形成新字符串:

>>> str = 'Hello World'
>>> newstr = str[:5] + ' New ' + str[6:]
>>> newstr
'Hello New World'

可变和不可变数据类型的区别在函数的参数传递时就非常重要了,后面再详述。

再来看tuple数据类型,它与list很相似,区别在于,tuple是用()包围的,而不是[]。更重要的是,tuple是不可变数据类型。
如果tuple只有一个元素,应在此元素后加逗号,否则会认为是一个独立的值。例如:

>>> type((1,))
<class 'tuple'>
>>> type((1))
<class 'int'>

type可以获取具体的数据类型。
tuple()和list()可实现list和tuple数据类型间的相互转换。

>>> list((1,2,3,4))
[1, 2, 3, 4]
>>> tuple([1, 2, 3, 4])
(1, 2, 3, 4)

引用

这里引用指的是reference。
准确的说,给变量赋值,实际是给变量赋予一个内存的地址。
函数id()可返回对象生命周期内的唯一地址,你可以认为是内存中地址。
下例说明了对象指向不可变对象和可变对象的区别:

>>> a=10
>>> id(a)
139865006684352
>>> a=20
>>> id(a)
139865006684672
>>> a=[1, 2, 3, 4]
>>> b=a
>>> id(a)
139864879096904
>>> id(b)
139864879096904
>>> a[0]=10
>>> a
[10, 2, 3, 4]
>>> id(a)
139864879096904
>>> id(b)
139864879096904

由于10,20都是整型,整型是不可变对象,因此当赋予a=20时,a的地址发生了变化,指向内存中新的地址。而list是可变数据类型,当改变list中的item时,指向list的地址,如a,b都不会改变。
再看一个参数传递的例子:

>>> def show_id(a, b):
...     print(id(a))
...     print(id(b))
...     a += 1
...     b += [3,]
...     print(id(a))
...     print(id(b))
... 
>>> a = 1
>>> b=[1,2]
>>> id(a)
139865006684064
>>> id(b)
139864879096328
>>> show_id(a, b)
139865006684064
139864879096328
139865006684096
139864879096328

当我们不希望传递引用,已避免原始数据被修改时,Python提供一个copy模块,其中的copy()可以复制原始的list或dictionary,如果原始的list中又包含了list,则可以使用deepcopy()。

>>> import copy
>>> a=[1, 2, 3, 4]
>>> b=copy.copy(a)
>>> id(b)
139864879096904
>>> id(a)
139864878994184
>>> b[0]=100
>>> a
[1, 2, 3, 4]
>>> b
[100, 2, 3, 4]

小程序: CONWAY’S GAME OF LIFE

康威生命游戏是一种模拟细胞自动衍生的游戏,由英国数学家John Horton Conway 发明,规则和详细说明见wiki
代码见conway.py
大致过程为,生成二维矩阵(list in list),其中每一个格子的细胞生死状态随机确定,然后就进入自动衍生状态。
程序中最关键的就是利用了deepcopy来拷贝现有矩阵,然后结合规则生成下一个矩阵,如此反复,直至永远。

发布了375 篇原创文章 · 获赞 43 · 访问量 55万+

猜你喜欢

转载自blog.csdn.net/stevensxiao/article/details/104089981