内置数据结构(变量类型)
list
set
dict
tuple ## list(列表)
一组由顺序的数据的组合
创建列表
空列表
In [24]:
1, 创建空列表
l1 = []
type是内置函数,负责打印出变量的类型
print(type(l1))
print(l1)
2. 创建带值的列表
l2 = [100]
print(type(l2))
print(l2)
3. 创建列表,带多个值
l3 = [2,3,1,4,6,4,6]
print(type(l3))
print(l3)
4. 使用list()
l4 = list()
print(type(l4))
print(l4)
<class ‘list’>
[]
<class ‘list’>
[100]
<class ‘list’>
[2, 3, 1, 4, 6, 4, 6]
<class ‘list’>
[]
列表常用操作
访问
使用下标操作(索引)
列表的位置是从0开始
分片操作
对列表进行任意一段的截取
l[:]
In [25]:
下标访问列表
l = [3,2,1,4,6,3,2]
print(l[3])
4
In [26]:
print(l[0])
3
In [31]:
分片操作
注意截取的范围,包含左边的下标值,不包含右边的下标值
print(l[1:4])
下标值可以为空,如果不写,左边下标值默认为0, 右边下标值为最大数加一,即表示截取到最后一个数据
print(l[:])
print(l[:4])
print(l[2:])
[2, 1, 4]
[3, 2, 1, 4, 6, 3, 2]
[3, 2, 1, 4]
[1, 4, 6, 3, 2]
In [36]:
print(l)
分片可以控制增长幅度,默认增长幅度为1
print(l[1:6:1])
打印从下标1开始的数字,每次隔一个
print(l[1:6:2])
下标可以超出范围,超出后不在考虑多余下标内容
print(l[2:10])
下标值,增长幅度可以为负数
为负数,表明顺序是从右往左
规定: 数组最后一个数字的下标是-1
[3, 2, 1, 4, 6, 3, 2]
[2, 1, 4, 6, 3]
[2, 4, 3]
[1, 4, 6, 3, 2]
[3, 2, 1]
In [40]:
分片之负数下标
print(l)
下面显示的是为空,因为默认分片总是从左向右截取
即正常情况,分片左边的值一定小于右边的值
print(l[-2:-4])
print(l[-4:-2])
如果分片一定左边值比右边大,则步长参数需要使用负数
此案例为一个list直接正反颠倒提供了一种思路
print(l[-2:-4:-1])
[3, 2, 1, 4, 6, 3, 2]
[]
[4, 6]
[3, 6]
分片操作是生成一个新的list
内置函数id,负责显示一个变量或者数据的唯一确定编号
In [44]:
id函数举例
a = 100
b = 200
print(id(a))
print(id(b))
c = a
print(id©)
如果a跟c只想一份数据,则更改a的值同样也会更改c的值
但是,显示结果并非如此,为什么?
a = 101
print(a)
print©
93941189949760
93941189952960
93941189949760
101
100
In [47]:
通过id可以直接判断出分片是从新生成了一份数据还是使用的同一份数据
l = [3,4,56,76,32,21,43,5]
ll = l[:]
lll = ll
如果两个id值一样,则表明分片产生的列表是使用的同一地址同一份数据
否则,则表明分片是从新生成了一份数据,即一个新的列表,然后把数值拷贝到新列表中
print(id(l))
print(id(ll))
print(id(lll))
通过id知道,ll和lll是同一份数据,验证代码如下
l[1] = 100
print(l)
print(ll)
ll[1] = 100
print(ll)
print(lll)
140226763582408
140226318124808
140226318124808
[3, 100, 56, 76, 32, 21, 43, 5]
[3, 4, 56, 76, 32, 21, 43, 5]
[3, 100, 56, 76, 32, 21, 43, 5]
[3, 100, 56, 76, 32, 21, 43, 5]
汉诺塔问题
规则:
每次移动一个盘子
任何时候大盘子在下面,小盘子在上面
方法:
n=1: 直接把A上的一个盘子移动到C上, A->C
n=2:
把小盘子从A放到B上, A->B
把大盘子从A放到C上, A->C
把小盘子从B放到C上, B->C
n=3:
把A上的两个盘子,通过C移动到B上去, 调用递归实现
把A上剩下的一个最大盘子移动到C上, A->C
把B上两个盘子,借助于A,挪到C上去, 调用递归
n = n:
把A上的n-1个盘子,借助于C,移动到B上去,调用递归
把A上的最大盘子,也是唯一一个,移动到C上,A->C
把B上n-1个盘子,借助于A,移动到C上, 调用递归
In [7]:
def hano(n, a, b, c):
'''
汉诺塔的递归实现
n:代表几个盘子
a:代表第一个塔,开始的塔
b:代表第二个塔,中间过渡的塔
c:代表第三个塔, 目标塔
'''
if n == 1:
print(a, "-->", c)
return None
if n == 2:
print(a, "-->", b)
print(a, "-->", c)
print(b, "-->", c)
return None
# 把n-1个盘子,从a塔借助于c塔,挪到b塔上去
hano(n-1, a, c, b)
print(a, "-->", c)
# 把n-1个盘子,从b塔,借助于a塔,挪到c塔上去
hano(n-1,b, a, c)
a = "A"
b = "B"
c = "C"
n = 1
hano(n, a, b, c)
A --> C
In [8]:
n = 2
hano(n, a, b, c)
A --> B
A --> C
B --> C
In [9]:
n = 3
hano(n, a, b, c)
A --> C
A --> B
C --> B
A --> C
B --> A
B --> C
A --> C
In [10]:
n = 5
hano(n, a, b, c)
A --> C
A --> B
C --> B
A --> C
B --> A
B --> C
A --> C
A --> B
C --> B
C --> A
B --> A
C --> B
A --> C
A --> B
C --> B
A --> C
B --> A
B --> C
A --> C
B --> A
C --> B
C --> A
B --> A
B --> C
A --> C
A --> B
C --> B
A --> C
B --> A
B --> C
A --> C
List(列表)
del: 删除命令
In [12]:
del 删除
a = [1,2,3,4,5,6]
del a[2]
print(a)
[1, 2, 4, 5, 6]
In [13]:
del 删除
如果使用del之后,id的值和删除前不一样,则说明删除生成了一个新的list
a = [1,2,3,4,5,6]
print(id(a))
del a[2]
print(id(a))
print(a)
140246810905416
140246810905416
[1, 2, 4, 5, 6]
In [14]:
del一个变量后不能在继续使用此变量
del a
print(a)
NameError Traceback (most recent call last)
in ()
1 del a
----> 2 print(a)
NameError: name ‘a’ is not defined
In [16]:
使用加号链接两个列表
a = [1,2,3,4,5]
b = [5,6,7,8,9]
d = [‘a’, ‘b’, ‘c’]
c = a + b + d
print©
[1, 2, 3, 4, 5, 5, 6, 7, 8, 9, ‘a’, ‘b’, ‘c’]
In [18]:
使用乘号操作列表
列表直接跟一个整数相乘
相当于把n个列表接在一起
a = [1,2,3,4,5]
b = a *3
print(b)
[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
In [21]:
成员资格运算
就是判断一个元素是否在爱list里边
a = [1,2,3,4,5,6]
b = 8
#c 的值是一个布尔值
c = b in a
print©
b = 4
print(b in a)
False
True
In [22]:
not in
a = [1,2,3,4,5]
b = 9
print(b not in a)
True
链表的遍历
for
while
In [28]:
for in list
a = [1,2,3,4,5]
挨个打印a里边的元素
for i in a:
print(i)
1
2
3
4
5
In [ ]:
java, c++ 程序员写的python代码是这样的
for i in range(0,len(a)):
print(a[i])
i += 1
In [24]:
b = [“I love wangxiaojing”]
for i in b:
print(i)
I love wangxiaojing
In [26]:
range
in 后面的变量要求是可以可迭代的内容
for i in range(1,10):
print(i)
print(type(range(1,10)))
1
2
3
4
5
6
7
8
9
<class ‘range’>
In [ ]:
while循环访问list
一般不用while遍历list
a = [1,2,3,4,5,6]
length = len(a)
indx表示的是list的下标
indx = 0
while indx < length:
print(a[indx])
indx += 1
In [27]:
双层列表循环
#a 为嵌套列表,或者叫双层列表
a = [[“one”, 1], [“two”, 2], [“three”, 3] ]
for k,v in a:
print(k, “–”, v)
one – 1
two – 2
three – 3
In [29]:
双层列表循环变异
#a 为嵌套列表,或者叫双层列表
a = [[“one”, 1, “eins”], [“two”, 2], [“three”, 3,4,5,6,8] ]
for k,v in a:
print(k, “–”, v)
ValueError Traceback (most recent call last)
in ()
4 a = [[“one”, 1, “eins”], [“two”, 2], [“three”, 3,4,5,6,8] ]
5
----> 6 for k,v in a:
7 print(k, “–”, v)
ValueError: too many values to unpack (expected 2)
In [32]:
双层列表循环变异
#a 为嵌套列表,或者叫双层列表
a = [[“one”, 1, “eins”], [“two”, 2,“zwei”], [“three”, 3,“drei”] ]
#这个例子说明,k,v,w的个数应该跟解包出来的变量个数一致
for k,v,w in a:
print(k, “–”, v, “–”,w)
one – 1 – eins
two – 2 – zwei
three – 3 – drei
列表内涵: list content
通过简单方法创作列表
In [33]:
for 创建
a = [‘a’, ‘b’, ‘c’]
用list a创建一个list b
下面代码的含义是,对于所有a中的元素,逐个放入新列表b中
b = [i for i in a]
print(b)
[‘a’, ‘b’, ‘c’]
In [35]:
对a中所有元素乘以10,生成一个新list
a = [1,2,3,4,5]
用list a创建一个list b
下面代码的含义是,对于所有a中的元素,逐个放入新列表b中
b = [i*10 for i in a]
print(b)
[10, 20, 30, 40, 50]
In [39]:
还可以过滤原来list中的内容病放入新列表
比如原有列表a, 需要把所有a中的偶数生成新的列表b
a = [x for x in range(1,35)] #生成从1到34的一个列表
把a中所有偶数生成一个新的列表 b
b = [m for m in a if m % 2 == 0]
print(b)
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34]
In [49]:
列表生成式可以嵌套
由两个列表a,b
a = [i for i in range(1,4)] # 生成list a
print(a)
b = [i for i in range(100,400) if i % 100 == 0]
print(b)
列表生成是可以嵌套,此时等于两个for循环嵌套
c = [ m+n for m in a for n in b]
print©
上面代码跟下面代码等价
for m in a:
for n in b:
print(m+n, end=" ")
print()
嵌套的列表生城市也可以用条件表达式
c = [ m+n for m in a for n in b if m+n < 250]
print©
[1, 2, 3]
[100, 200, 300]
[101, 201, 301, 102, 202, 302, 103, 203, 303]
101 201 301 102 202 302 103 203 303
[101, 201, 102, 202, 103, 203]
关于列表的常用函数
In [53]:
len:求列表长度
a = [x for x in range(1,100)]
print(len(a))
max:求列表中的最大值
min: 同理
print(max(a))
b = [‘man’, ‘film’, ‘python’]
print(max(b))
99
99
python
In [55]:
list:将其他格式的数据转换成list
a = [1,2,3]
print(list(a))
[1, 2, 3]
In [56]:
s = “I love wangxiaojing”
print(list(s))
[‘I’, ’ ', ‘l’, ‘o’, ‘v’, ‘e’, ’ ', ‘w’, ‘a’, ‘n’, ‘g’, ‘x’, ‘i’, ‘a’, ‘o’, ‘j’, ‘i’, ‘n’, ‘g’]
In [57]:
把range产生的内容转换成list
print(list(range(12, 19)))
[12, 13, 14, 15, 16, 17, 18]
传值和传地址的区别
对于简单的数值,采用传值操作,即在函数内对参数的操作不影响外面的变量
对于复杂变量,采用传地址操作,此时函数内的参数和外部变量是同一份内容,
任何地方对此内容的更改都影响另外的变量或参数的使用
def a(n):
n[2] = 300
print(n)
return None
def b(n):
n += 100
print(n)
return None
an = [1,2,3,4,5,6]
bn = 9
print(an)
a(an)
print(an)
print(bn)
b(bn)
print(bn)
[1, 2, 3, 4, 5, 6]
[1, 2, 300, 4, 5, 6]
[1, 2, 300, 4, 5, 6]
9
109
9
关于列表的函数
In [3]:
l = [‘a’,“i love wangxiaojing”, 45, 766, 5+4j]
l
Out[3]:
[‘a’, ‘i love wangxiaojing’, 45, 766, (5+4j)]
In [4]:
append 插入一个内容, 在末尾追加
a = [ i for i in range(1,5)]
print(a)
a.append(100)
print(a)
[1, 2, 3, 4]
[1, 2, 3, 4, 100]
In [6]:
insert: 制定位置插入
insert(index, data), 插入位置是index前面
print(a)
a.insert(3, 666)
print(a)
[1, 2, 3, 4, 100]
[1, 2, 3, 666, 4, 100]
In [7]:
删除
del 删除
pop,从对位拿出一个元素,即把最后一个元素取出来
print(a)
last_ele = a.pop()
print(last_ele)
print(a)
[1, 2, 3, 666, 4, 100]
100
[1, 2, 3, 666, 4]
In [11]:
remove:在列表中删除指定的值的元素
如果被删除的值没在list中,则报错
即,删除list指定值的操作应该使用try。。。excepty语句,或者先行进行判断
if x in list:
list.remove(x)
a.insert(4, 666)
print(a)
print(id(a))
a.remove(666)
print(a)
print(id(a))
输出两个id值一样,说明,remove操作是在原list直接操作
[1, 2, 3, 4, 666]
140249408978184
[1, 2, 3, 4]
140249408978184
In [12]:
clear:清空
print(a)
print(id(a))
a.clear()
print(a)
print(id(a))
如果不需要列表地址保持不变,则清空列表可以使用以下方式
a = list()
a = []
[1, 2, 3, 4]
140249408978184
[]
140249408978184
In [13]:
reverse:翻转列表内容,原地翻转
a = [ 1,2,3,4,5]
print(a)
print(id(a))
a.reverse()
print(a)
print(id(a))
[1, 2, 3, 4, 5]
140249409135624
[5, 4, 3, 2, 1]
140249409135624
In [14]:
extend:扩展列表,两个列表,把一个直接拼接到后一个上
a = [ 1,2,3,4,5]
b = [6,7,8,9,10]
print(a)
print(id(a))
a.extend(b)
print(a)
print(id(a))
[1, 2, 3, 4, 5]
140249408367816
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
140249408367816
In [18]:
count:查找列表中指定值或元素的个数
print(a)
a.append(8)
a.insert(4, 8)
print(a)
a_len = a.count(8)
print(a_len)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 8]
[1, 2, 3, 4, 8, 5, 6, 7, 8, 9, 10, 8, 8]
4
In [22]:
copy: 拷贝,此函数是浅拷贝,
列表类型变量赋值示例
a = [1,2,3,4,5,666]
print(a)
list类型,简单赋值操作,是传地址
b = a
b[3] = 777
print(a)
print(id(a))
print(b)
print(id(b))
print("*" * 20)
为了解决以上问题,list赋值需要采用copy函数
b = a.copy()
print(a)
print(id(a))
print(b)
print(id(b))
print("*" * 30)
b[3] = 888
print(a)
print(b)
[1, 2, 3, 4, 5, 666]
[1, 2, 3, 777, 5, 666]
140249408975432
[1, 2, 3, 777, 5, 666]
140249408975432
[1, 2, 3, 777, 5, 666]
140249408975432
[1, 2, 3, 777, 5, 666]
140249408976776
[1, 2, 3, 777, 5, 666]
[1, 2, 3, 888, 5, 666]
In [26]:
深拷贝跟浅拷贝的区别
出现下列问题的原因是,copy‘函数是个浅拷贝函数,即只拷贝一层内容
深拷贝需要使用特定工具
a = [1,2,3, [10, 20, 30]]
b = a.copy()
print(id(a))
print(id(b))
print(id(a[3]))
print(id(b[3]))
a[3][2] = 666
print(a)
print(b)
140249408365768
140249409236040
140249409236232
140249409236232
[1, 2, 3, [10, 20, 666]]
[1, 2, 3, [10, 20, 666]]