乐趣区

Python教程03集合与循环

大纲

  • 集合类型
  • 列表
  • 元组
  • 字典
  • 集合
  • 循环
  • 练习

集合类型

基础语法中介绍的几种 python 的基础类型都属于 数值类型
另外一种基础类型是 集合类型 ,主要包括 列表 元组 字典 集合
其中 列表 元组 是一种 序列 序列 是一种将一串 元素 按顺序组合在一起的 数据结构
序列的特点是拥有 索引操作 切片操作
索引操作 是从序列中通过编号获得其中的一个元素,语法是中括号 [编号]
切片操作 是获取一部分序列,语法为 [编号 1: 编号 2]

回忆 字符串 ,是不是也有相同的操作,获取其中某个或某段字符。
所以字符串其实也是一种序列,其元素就是单个字符。

列表

列表 是一种 有序 序列 ,其 元素 可以是 任意类型 ,编号从0 开始到 长度 -1结束。
创建一个列表 :Python 中使用 中括号 [] 来表示列表。注意与索引切片区分。

name_list = ['Green', 'Lucy', 'Lily']   # 字符串列表
score_list = [98, 67, 80]               # 整数列表
x_list = ['hello', 98, 2.15, True]      # 任意类型列表
y_list = [score_list, name_list]        # 列表的列表

获取列表长度len

print(len(name_list))   # 列表长度

索引与切片

print(score_list[1])    # 索引,返回元素
print(x_list[0:1])      # 切片,返回列表

输出:

如何理解列表的列表?

y_list = [score_list, name_list]

列表中可以放任意类型的数据,放一个序列类型肯定是没有问题的。
专业的说法是 二维列表 ,当然还可以继续嵌套形成 多维列表
访问方式:

print(y_list[1][2])     # 访问多维列表

通过第一个 [] 获得第一维的列表,再用 [] 就可以得到第二维的数据了。
等价于

_name_list = y_list[1]
print(_name_list[2])

修改元素:直接通过赋值就可以修改其中的元素。

name_list[2] = 'Kate'

逻辑判断innot in 判断列表中是否存在某个元素。

if 'Green' in name_list:
    print('Green is here')
if 'Lucy' not in name_list:
    print('Lucy is not here')

加法与乘法
加号(+)会将两个列表组合起来产生一个新列表。

# 加法
x = [1, 3, 2]
y = [4, 6, 5]
z = x + y
print(x + y)

输出:
乘号(*)则会将原列表进行复制,产生新列表。

# 乘法
x = [1, 2, 3]
z = x * 3
print(z)

输出:

最大值与最小值maxmin

x = [1, 2, 3]
print(max(x))
print(min(x))

输出:

如果列表内的元素必须是 可比较 的。试试字符串列表能不能用?

排序sort。将列表内的元素从小到大进行排序。

# 排序
x = [1, 2, 4, 5, 3, 2]
x.sort()
print(x)

输出:

翻转列表reverse。把列表进行翻转,后面到前面。

x.reverse() 

将上面排序好的进行翻转就得到

索引 index,获得某个元素在列表中 第一次 出现的 位置

x = [1, 2, 3, 2]
i = x.index(2)
print(i)

2 第一次出现在位置 1,所以输出 1。当元素 不存在 时,该方法会 报错
可以先判断是否存在,再做索引。或者使用后面介绍的 tryexcept 来处理。

if 9 in x:
    i = x.index(9)
    print(i)

统计元素个数count

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

x 列表中元素 2 出现了 2 次,所有该方法返回 2。

尾部添加 appendextend
两个都是在尾部添加,区别在于 append 添加的是 元素 extend 添加的是 列表

x = [1, 2, 3]
x.append(100)
print(x)
x.extend([200, 300])
print(x)

输出:
extend的效果相当于

x = x + [200, 300]

插入元素insert。在列表的某个位置插入某个元素,insert(位置,元素)

x = [1, 2, 3]
x.insert(0, 0)
x.insert(2, 100)
print(x)

输出:
x 列表先在位置 0(即列表开头)插入了 0,然后又在位置 2 插入了 100。

删除 removedelpopclear
remove 删除 第一个出现 的该元素,如果 不存在 时与 index 一样会 报错
del 则是根据 索引位置 进行删除,当索引 超出范围 时会 报错
pop 会删除 最后 一个元素,并将其 返回
clear 删除 所有 列表中元素。

x = [1, 2, 3, 2]
x.remove(2)     # 删除第一个 2 元素
del x[1]        # 删除位置 1 的元素
p = x.pop()     # 删除最后一个 2,同时 p 被赋值 2
x.clear()       # 删除所有元素

元组

元组 列表 是一个的 区别 就是元组是一种 不可变序列 ,其他都与列表一样。
元组拥有序列的通用操作,但会改变序列的方法都不存在。
创建一个元组 :Python 中使用 括号 () 来表示元组。单只有一个元素时,要加一个 逗号

a = (1,)       # 只有一个元素的元组
b = (1, 3, 4)   # 元组

序列通用操作

print(len(a))   # 长度
print(b[1])     # 索引
print(b[0:2])   # 切片
print(max(b))   # 最大值
print(min(b))   # 最小值
print(2 in b)   # in

输出:

元组与列表的转换listtuple

tuple([1, 2, 3])    # 转换为元组
list((1, 2, 3))     # 转换为列表

拆包 :拆包是将元组或列表中的 所有元素 逐个 赋值 多个变量

x = ('a', 'b', 'c')
a, b, c = x
print(a, b, c)

输出:
a,b,c 三个变量用 逗号 隔开,并按顺序被赋值上 x 元组中的三个值。
变量的数量必须与元组的 长度一样

字典

字典 是一种 无序 的结构,同样可以放入 任意类型 元素。
列表 使用 0,1,2…进行 有序 索引不同,字典 使用 自定义 关键字 进行索引。
key-value 结构 key 代表用来索引的 关键字 value 代表存储的 元素 。【 键值对
创建一个字典 :使用 大括号 {} 包裹字典,每个 键值对 逗号 隔开,键值对 中用 冒号 分隔 keyvalue,前面的是 key,后面的是 value。

user = {
    'name': 'Green',
    'age': 12,
    'gender': 'male'
}

写成一行

user = {'Green': 80, 'Lily': 90, 'Lucy': 76}

也是可以的,但大部分情况分行书写会比较清晰。

如何取值 :同样是通过 [] 来进行,只不过将列表里的编号换成 key 值就可以取到 value。

print(user['name'])

当 key不存在 时,会 报错

安全取值 get,如果 key 不存在时,使用get 方法可以 避免报错 ,并返回一个 空值 None

address = user.get('address')  # 返回 None,因为没有 address 这个 key
name = user.get('name')  # 返回 Green

添加与修改:直接赋值。

user['address'] = 'china'  # 添加一个 address 键值对
user['age'] = 18           # age 被修改为 18

删除del

del user['gender']  # 删除了 gender 这个键值对

清空clear

user.clear()        # 清空了所有键值对

判断存在 keyin

if 'age' in user:           # 判断 age 是否在 user 里面
    print(user['age'])      

获得字典的所有内容keysvaluesitems

print(user.keys())      # 获得所有 key 值
print(user.values())    # 获得所有 value 值
print(user.items())     # 获得所有键值对

输出:
输出的值并不是列表,可以用 list 方法转换为列表,方便使用。

复杂结构 :通过 字典 列表 互相嵌套,就能实现实际开发中常用的结构。

users = [{'name': 'Green', 'age': 12, 'like': ['apple']},
    {'name': 'Lucy', 'age': 13, 'like': ['apple', 'pear']}, 
    {'name': 'Lily', 'age': 11, 'like': ['orange', 'melon']}
]

获得某个用户的第一个喜好。

print(users[1]['like'][0])

通过多个 [] 的提取,最后就提取到了用户 1【Lucy】的第一个喜好。

集合

集合 是一组 key 组成的数据,与 字典 区别 在于 没有 value
列表 区别 在于每个元素 key不可重复
在数学上可以进行 交集 并集 差集 等运算,是一种在特定场合很方便的数据结构。
创建集合 :与字典一样,使用 大括号 {} 表示集合,但不需要有 value。

set1 = {'apple', 'orange', 'melon'}
set2 = {'apple', 'pear'}

列表去重 :使用set 方法将列表 转换 为集合,可以很方便的对列表去重。

print(set([1, 3, 3, 4]))    # 列表去重
print(set('class'))         # 字符串也是一种序列

输出:
输出的结果自动删除了重复的值,然后还可以再用 list 转换为列表,就是去重后的列表了。

交集 :set1 & set2,计算两个集合中相同的元素。
并集 :set1 | set2,计算两个集合所有的不重复元素。
差集 :set1 set2,计算 set1 中有,但 set2 中没有的元素。
对称差集:set1 ^ set2,计算只存在于 set1 或 set2 中的元素。

set1 = {'apple', 'orange', 'melon'}
set2 = {'apple', 'pear'}
print(set1 & set2)  # 交集
print(set1 | set2)  # 并集
print(set1 - set2)  # 差集
print(set1 ^ set2)  # 对称差集

输出:

添加元素add

s = {'apple', 'orange'}
s.add('pear')

删除元素removediscardpopclear

s.remove('apple')       # 如果不存在该元素,会报错。s.discard('apple1')     # 更安全的删除,即使不存在也不报错
x = s.pop()             # 随机删除集合是中的一个元素,并返回它
s.clear()               # 删除集合中的所有元素

子集与超集的判断issubsetissuperset

set1 = {'a', 'b', 'c'}
set2 = {'a'}        # set2 是 set1 的子集,set1 是 set2 的超集
set2.issubset(set1)     # 返回 True
set1.issuperset(set2)   # 返回 True

循环

循环 语句用于处理具有 重复性 的工作,经常用于处理列表、字典等结构。
如一个列表中有几十万个元素,这时候就需要用循环来 遍历 所有元素。
遍历 是一种从集合中逐个获取元素的操作。

for 循环forin

names = ['Green', 'Lucy', 'Lily']
for name in names:
    print('Happy Birthday, {}'.format(name))

输出:
for打头开始一个循环,in后面的 names 表示要遍历的列表。
for后面的 name 是一个 临时变量 ,用来 存储 遍历过程中的每个 元素
0N-1 的元素按顺序依次 赋值 临时变量 ,并 重复执行 下面的 代码块 N 次。(N 等于列表的长度)

编写一个程序,计算列表中所有元素的总和。

numbers = [10, 53, 45, 44, 907] # 要计算的列表
answer = 0                      # 总和初始化为 0
for i in numbers:               # 开始循环
    answer = answer + i         # 逐个相加
print(answer)

每次循环 i 都会被 赋值 为 numbers 里的一个值。
将当前的 answer 加上 i,并将结果赋值给 answer。
每次循环 都更新了 answer,当 循环结束 时就是列表的总和了。
sum方法,同样也可以完成这个功能,可以将结果进行对比。

sum(numbers)

这里我们初步了解到了方法到底在做什么。

停止循环 break
在 for 循环代码块中出现 break,就会停止 这个 for 循环
一般我们会与 条件判断 一起使用,实现 满足条件 后停止循环。
下面我们一起实现一个 index 功能。【返回第一次出现的位置,不存在时返回 -1】

numbers = [10, 53, 45, 44, 907]
i = 0                   # 记录当前遍历到的位置
index = -1              # 结果默认为 - 1 不存在
for number in numbers:
    if number == 53:    # 满足条件
        index = i       # 赋值位置
        break           # 停止循环
    i = i + 1           # 位置 +1
print(index)

这里的 i 记录了当前遍历到的位置,所以在每次循环执行的最后要加 1。
如果你打印出 i 的值,会发现 i 停止在了满足条件的位置,即循环停止了。

中断循环 continue
在循环中出现 continue,就会停止该次循环,马上进行 下一轮 循环。
下面我们还是实现一个求和的功能,但如果数字大于 100 时不计算在内。

numbers = [10, 53, 45, 44, 907]
answer = 0
for i in numbers:
    if i > 100:
        continue    # 马上开始下一个循环
    answer = answer + i
print(answer)

当大于 100 时,就跳过,不进行相加。
也许你已经发现其实不用 continue 也可以实现这个功能。

if i <= 100:
    answer = answer + i

所以 continue 的出镜率并不高,一般在逻辑异常复杂时非常好用。

while 循环 while
while 循环是根据 条件判断 来是否 继续循环 的。

names = ['Green', 'Lucy', 'Lily']
i = 0   # 索引位置从 0 开始
while i < len(names):    ~~~~# 条件为 True 时,继续循环
    name = names[i]      # 通过索引获得元素
    print('Happy Birthday, {}'.format(name))
    i = i + 1            # 索引 +1

while后面的 条件语句 就是要判断的内容,为 True 时循环 继续 ,为False 时循环 停止
这是我们写的第一个 for 循环的 while 版本。条件为索引值小于列表长度。
while同样支持 breakcontinue
while 和 for 循环是基本等价的不同写法,根据需要选择更方便的写法。

# 无限循环
while True:
    print(1)

range:生成一个整数序列。在 for 循环中常用。

for i in range(10):     # 0 到 9 的序列
    print(i)
range(3, 10)            # 3 到 9 的序列
range(3, 10, 2)         # 3,5,7,9 步长为 2 的序列

range可以生成 从 a 到 b ,且 步长为 n 整数序列
for 循环的 range 版本:

names = ['Green', 'Lucy', 'Lily']
for i in range(len(names)):
    name = names[i]
    print('Happy Birthday, {}'.format(name))

这里使用 len(names) 来生成 全部的索引,经常处理列表时有需要索引值时可以这样做。

循环的嵌套

for i in range(1, 10):
    for j in range(1, 10):
        print('{} * {} = {}'.format(i, j, i*j))

九九乘法表的生成。
上面的乘法表有个问题,就是生成了 1 * 2 和 2 * 1 两个,这时我们通过加入 continue 解决。

for i in range(1, 10):
    for j in range(1, 10):
        if j < i:
            continue
        print('{} * {} = {}'.format(i, j, i*j))

breakcontinue 在循环中只作用于它 所处的循环,这个要特别注意。

字典的循环 :字典类型同样可以用循环来处理。
1、通过keys 循环遍历所有key

user = {'name': 'Green', 'age': 12, 'address': 'china'}
for key in user.keys():
    print('{} : {}'.format(key, user[key]))

2、通过 items 循环遍历所有 键值对

for key, value in user.items():
    print('{} : {}'.format(key, value))

与之前的 for 循环不一样的地方就在于 items 方法返回的列表中元素是一个 元组 【键值对】。
所以在接收时就要用 keyvalue两个变量去将其 拆包,这样就可以同时遍历到 key 和 value。

练习

编写一个获得列表中最大值的程序。
编写一个获得列表中最小值的程序。
编写一个计算列表所有值的平均值的程序。


github: https://github.com/lvancer/course_python

退出移动版