Python(8)序列、列表、元组、字符串以及迭代器和可迭代对象

序列

  • 序列是Python中最基本的一种数据结构
  • 序列用于保存一组有序的数据,所有的数据在序列当中都有一个唯一的位置(索引) 并且序列中的数据会按照添加的顺序来分配索引
  • 序列的分类:
    • 可变序列(序列中的元素可以改变)
      • 列表(list)
    • 不可变序列(序列中的元素不可以改变)
      • 元组(tuple)
      • 字符串(str)

切片

单独取值


students = ["孙悟空", "猪八戒", "沙和尚", "唐三藏"]

print(students[0])

# 切片可以是负数(从尾部取)

print(students[-1])

范围取值

  • 列表[起始:结束:步长]
    • 通过切片获取元素时,会包括起始位置的元素,但不会包括结束位置的元素。
    • 做切片操作时,会返回一个新的序列,不会影响之前的序列
    • 起始(序列的最开始)和结束(序列的最后位置)位置的索引可以省略不写
    • 步长表示,每次获取元素的间隔(默认为1)
    • 步长不可以是0,但可以是负数
students = ["孙悟空", "猪八戒", "沙和尚", "唐三藏"]
print(students[1:3])  # ['猪八戒', '沙和尚']
print(students[1:-1])  # ['猪八戒', '沙和尚']
print(students[1:])  # ['猪八戒', '沙和尚', '唐三藏']
print(students[:3])  # ['孙悟空', '猪八戒', '沙和尚']

a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[0:6:2])  # [1, 3, 5]
print(a[::-1])  # [9, 8, 7, 6, 5, 4, 3, 2, 1]
print(a[::-2])  # [9, 7, 5, 3, 1]

序列于+ 和 ×

a = [1, 2, 3]
b = [4, 5, 6]
print(a + b)

c = [1, 2, 3] * 5
print(c)

序列和 in 和 not in

  • in就是用来检测指定元素是否存在于序列中
    • 如果在 True 如果不在就是False
  • not in 用来检测元素是否不在序列中
a = [1, 2, 3]
print(1 in a)  # True
print(4 not in a)  # True

len() 获取序列元素的个数

min() 获取序列中的最小值

max() 获取序列中的最大值

index() 获取指定元素第一次出现时的索引

index(“str”,1,5)在索引 1 到 5 之间的位置 查找指定元素

count() 统计指定元素出现的次数

map()、filter()

  • map
    • map() 函数会根据提供的函数对指定的可迭代对象的每个元素进行运算,并将返回运算结果的迭代器
  • filter
    • filter()函数会根据提供的函数对指定的可迭代对象的每个元素进行运算,并将运算结果为True的元素,以迭代器的形式返回
# 定义一个列表(可迭代对象)
s = [1, 2, 3, 4]


# 定义一个函数,这个函数的功能是,如果是偶数则返回数字本身,如果不是偶数则返回None
def odd(num):
    if num % 2 == 0:
        return num
    else:
        return None


# map(odd,s) 第一个参数是函数名,第二个参数是可迭代对象
# 由于返回的是一个迭代器,我们需要将其转换成一个列表,所以使用list转换
map_lise = list(map(odd, s))

# filter(odd,s) 第一个参数是函数名,第二个参数是可迭代对象
# filter只会返回结果为True的值,None是空性,所以为False不返回,这里就把偶数过滤了出来
filter_list = list(filter(odd, s))

print(map_lise)
print(filter_list)

列表

  • 列表是Python中的一个对象
  • 列表中可以保存多个有序的数据,列表是用来存储对象的对象

列表的方法

append

a = ["孙悟空"]
a.append("猪八戒")
print(a)

insert

a = ["孙悟空"]
a.insert(0, "唐三藏")
print(a)

extend

a = ["孙悟空"]
# a.extend(["白龙马","沙和尚"])
a += ["白龙马", "沙和尚"]
print(a)

clear()

a = ["孙悟空"]
a.clear()
print(a)

pop,remove

pop 按照索引删除,如果不添加索引则删除最后一个元素

a = ["孙悟空","猪八戒"]
a.pop(0) # ['猪八戒']
a.pop() # ['孙悟空']

remove 删除目标元素

a = ["孙悟空","猪八戒"]
a.remove("猪八戒") # ["孙悟空"]

reverse

a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
a.reverse() # 列表翻转

sort

a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

a.sort()   # 默认升序

a.sort(reverse=True)   # reverse = True 表示为降序

列表循环

while循环

a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

count = 0

while count < len(a):

    print(a[count])
    count += 1

for循环

a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

for i in a:
    print(i)

列表的拷贝

列表中存储的只是对象的引用并不是对象本身,变量也同理。

  • x 是变量 存储的是列表的引用

  • 列表中的1 2 3 也是引用并不是本身

  • 当 将x赋值给y后 赋值的也是引用并不是值,不是值!不是值!!
    在这里插入图片描述

  • 当我们修改变量 y 的值后,再输出y和x发现x也被修改,因为他们是同一个引用

代码如下所示:

x = [1, 2, 3]
y = x
y[1] = 1
print(y)  # [1, 1, 3]
print(x)  # [1, 1, 3]

我们只可以使用copy或切片来实现列表的值的复制

x = [1, 2, 3]
y = x.copy()  # y = x[:]
y[2] = 1
print(y)
print(x)

但当我们使用嵌套列表时就又不管用了

x = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
y = x.copy()
y[1][1] = 3
print(y)  # [[1, 2, 3], [1, 3, 3], [1, 2, 3]]
print(x)  # [[1, 2, 3], [1, 3, 3], [1, 2, 3]]

这时我们可以使用深拷贝

import copy

x = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
y = copy.deepcopy(x)
y[1][1] = 3
print(y)  # [[1, 2, 3], [1, 3, 3], [1, 2, 3]]
print(x)  # [[1, 2, 3], [1, 2, 3], [1, 2, 3]]

列表推导式

思考

将一个由数字组成的列表中的数字全部翻倍

原始写法

a = [1, 2, 3, 4, 5, 6]
for i in range(len(a)):
    a[i] = a[i] * 2

推导式

a = [1, 2, 3, 4, 5, 6]
a = [i * 2 for i in a]
print(a)

推导式语法
[expression for target in iterable]

[表达式 for 目标 in 可迭代对象]

小案例

将0-9存到列表

将列表 0-9 的数值分别+1后填入列表

# 将0-9存到列表
print([i for i in range(10)])

# 将列表 0-9 的数值分别+1后填入列表
print([i + 1 for i in range(10)])

推导式的嵌套

将 [[1,2,3],[4,5,6],[7,8,9]] 二位数组展开

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print([col for i in matrix for col in i])

推导式条件添加

[“A”, “B”, “C”, “A”] 将列表中的 A 存入新列表

words = ["A", "B", "C", "A"]
print([word for word in words if word == "A"])

推导式嵌套时添加条件

# 推导式
print([[x, y] for x in range(10) if x % 2 == 0 for y in range(10) if y % 3 == 0])

# 相同作用的 for 循环
b = []
for x in range(10):
    if x % 2 == 0:
        for y in range(10):
            if y % 3 == 0:
                b.append([x, y])
print(b)

元组

元组也是序列,是不可变序列

可以使用序列的所有方法

相较于列表来说,最大的区别就是不可变

元组有推导式么?

元组没有推导式

s = (1, 2, 3, 4)

# 列表推导式
print([i for i in s])  # [1, 2, 3, 4]

# 这个返回的是一个生成器
print((i for i in s))  # <generator object <genexpr> at 0x0000021102C619E0>

如何生成一个只有一个元素的元组?

为什么会有这个问题呢?请看以下案例

s = (123)
print(type(s))  # <class 'int'>

# 正确写法 在元素后面加一个逗号
s = (123,)
print(type(s))  # <class 'tuple'>

元组的打包和解包

打包就是简单的创建一个元组,而解包就是用对应数量的变量接收

# 打包
s = (1, 2, 3)

# 解包
a, b, c = s

print(a)  # 1
print(b)  # 2
print(c)  # 3

不仅是元组可以,所有序列都可以

# 字符串
s = "123"
a, b, c = s
print(a)  # 1
print(b)  # 2
print(c)  # 3

# 列表
s = [1, 2, 3]
a, b, c = s
print(a)  # 1
print(b)  # 2
print(c)  # 3

我们还可以使用 * 去用更少的变量解包

# 打包
s = (1, 2, 3, 4, 5, 6)

# 解包
a, b, *c = s

print(a)  # 1
print(b)  # 2
print(c)  # [3, 4, 5, 6]

震惊元组不可变被推翻!竟然可以修改!

先来看案例:

a = ([1, 2, 3], [4, 5, 6])
a[0][0] = 9
print(a)  # ([9, 2, 3], [4, 5, 6])

通过观察可以发现,元组中的列表确实变了!不是不可变的么?这是为什么?

元组中的变量发生改变是真实发生的,但元组并未改变。

当我们使用索引 a[0] 获取到的元素获取到的是列表,我们改变的是列表第0个位置的值,列表就是可变,所以可以理解为列表的id并未改变。

看如下代码你就明白了

a = ([1, 2, 3], [4, 5, 6])
print("元组id", id(a))  # 元组id 1979716155456
print("未改变前列表id", id(a[0]))  # 未改变前列表id 1977868906304

a[0][0] = 9
print(a)  # ([9, 2, 3], [4, 5, 6])

print("改变后列表id", id(a[0]))  # 改变后列表id 1977868906304
print("改变后元组id", id(a))  # 改变后元组id 1979716155456

字符串

字符串也属于不可变序列,拥有所有不可变序列的所有特性

练习

判断一个字符串是不是回文数

  • 回文数
    • 正着反着都一样
    • 例如:“12321”
s = "12321"

print("是回文数") if s == s[::-1] else print("不是回文数")

迭代器和可迭代对象

  • 迭代器
    • 迭代器肯定是一个可迭代对象
    • 迭代器不可以重复使用,是一次性的
  • 可迭代对象
    • 迭代对象是可以重复使用的
s = [1, 2, 3, 4]  # 可迭代对象


def odd(num):
    if num % 2 == 0:
        return num
    else:
        return None


map_iter = map(odd, s)  # 返回一个迭代器

# 当我们使用了这个迭代器后
for i in map_iter:
    print(i)

# 再次使用迭代器为空
print(list(map_iter))

我们还可以使用iter()将一个可迭代对象转换成一个迭代器

x = [1, 2, 3, 4]
y = iter(x)

print(type(x))  # <class 'list'>
print(type(y))  # <class 'list_iterator'>

print(list(y))  # [1, 2, 3, 4]
print(list(y))  # []

next()

next() 针对迭代器使用的 作用是将迭代器中的对象逐个提取出来

x = [1, 2, 3, 4]
y = iter(x)

print(next(y))  # 1
print(next(y))  # 2
print(next(y))  # 3
print(next(y))  # 4

print(next(y))  # 报错,因为迭代器中没有元素了
"""
Traceback (most recent call last):
  File "D:\work\python_work_space\attend-classclass-begins\teacher\python_S\test.py", line 8, in <module>
    print(next(y))  
StopIteration
"""

我们可以使用next()第二个参数改变没有元素时的返回值

x = [1, 2, 3, 4]
y = iter(x)

print(next(y))  # 1
print(next(y))  # 2
print(next(y))  # 3
print(next(y))  # 4

print(next(y,"没有了!别下一个了!"))  # 没有了!别下一个了!
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值