当前位置: 首页 > news >正文

学习日志20 python

1 序列(Sequence)

在 Python 中,序列(Sequence)是一种基本的数据结构类别,指的是有序的元素集合。序列中的每个元素都可以通过索引(位置编号)来访问。Python 提供了多种内置的序列类型,包括最常用的 列表(List)、元组(Tuple)、字符串(String),以及不太常见的 范围(range)、字节序列(bytes、bytearray) 等。

序列的共同特点

  1. 有序性:元素按照特定顺序排列,可以通过索引访问。索引从 0 开始,也支持负数索引(如 -1 表示最后一个元素)。
  2. 可迭代:可以使用 for 循环遍历元素。
  3. 支持切片:可以通过切片操作(如 seq[start:stop:step])获取子序列。
  4. 通用操作:支持 len() 获取长度、in 判断元素是否存在、+ 拼接序列等。

常见序列类型

1. 列表(List)
  • 特点:可变(可修改)、用方括号 [] 定义。

python

运行

fruits = ["apple", "banana", "cherry"]
fruits[0] = "grape"  # 修改元素
print(fruits[1])     # 输出: banana
2. 元组(Tuple)
  • 特点:不可变(创建后不能修改)、用圆括号 () 定义。

python

运行

point = (3, 4)
print(point[0])      # 输出: 3
# point[0] = 5      # 错误:元组不可变
3. 字符串(String)
  • 特点:不可变的字符序列,用引号定义。

python

运行

s = "hello"
print(s[1])          # 输出: e
# s[1] = 'a'        # 错误:字符串不可变

序列的常用操作

以下是所有序列类型都支持的操作:

操作描述
seq[i]获取索引 i 处的元素。
seq[start:stop]获取从 start 到 stop-1 的切片。
len(seq)获取序列的长度。
x in seq判断元素 x 是否存在于序列中。
seq1 + seq2拼接两个序列(生成新序列,元组和字符串需类型相同)。
seq * n重复序列 n 次(生成新序列)。
min(seq) / max(seq)返回序列中的最小 / 最大值(元素需可比较)。
sorted(seq)返回排序后的新序列(不修改原序列)。

序列的优势

  1. 统一的接口:多种类型共享相同的操作方法,降低学习成本。
  2. 高效处理:底层优化使得序列操作非常快速。
  3. 灵活应用:适合各种场景,如数据存储、循环遍历、字符串处理等。

总结

序列是 Python 中最基础且重要的数据结构之一,掌握列表、元组和字符串等序列类型的使用,是编写高效 Python 代码的关键。如果需要存储可变数据且经常修改,推荐使用列表;如果数据不可变或需要作为字典键,使用元组;处理文本时则使用字符串。

2 在 Python 中,不是所有特殊方法都会自动生成

题目

根据以下程序,下列选项中,说法正确的是()class Foo():def __init__(self):passdef __getitem__(self,pos):return range(0,30,10)[pos]foo = Foo()A foo对象表现得像个序列B 可以使用len(foo)来查看对象foo的元素个数C 可以使用for i in foo:print(i)来遍历foo的元素D 不能使用foo[0]来访问对象foo的第一个元素正确答案:C

在 Python 中,不是所有特殊方法都会自动生成,这取决于类的定义方式。让我通过例子详细解释:

1. __len__ 必须显式定义

Python 不会为类自动生成 __len__ 方法。如果类需要支持 len(obj)必须自己实现

python

运行

class MyList:def __init__(self, data):self.data = data# 必须定义 __len__ 才能使用 len()def __len__(self):return len(self.data)obj = MyList([1, 2, 3])
print(len(obj))  # 输出: 3

如果没有实现 __len__,调用 len(obj) 会报错:

python

运行

class BadList:def __init__(self, data):self.data = dataobj = BadList([1, 2, 3])
print(len(obj))  # 报错: TypeError: object of type 'BadList' has no len()

2. __getitem__ 的作用

实现 __getitem__ 后,类实例可以像序列一样使用下标访问(如 obj[0]),但仍不是完整的序列

python

运行

class Foo:def __getitem__(self, pos):return [0, 10, 20][pos]  # 返回固定序列foo = Foo()
print(foo[0])  # 输出: 0
print(foo[1])  # 输出: 10

虽然能下标访问,但 Foo 不是序列,因为缺少 __len__

python

运行

print(len(foo))  # 报错: TypeError

3. for 循环的隐式调用

Python 的 for 循环更灵活:

  • 如果对象有 __iter__,优先调用它(如列表、字典)。
  • 如果没有 __iter__,尝试用 __getitem__ 从 0 开始依次读取元素,直到出现 IndexError

例子

python

运行

class Foo:def __getitem__(self, pos):if pos < 3:  # 限制范围return pos * 10raise IndexError  # 超出范围时触发结束循环foo = Foo()
for i in foo:print(i)  # 输出: 0, 10, 20

4. 哪些方法会自动生成?

Python 不会自动生成任何特殊方法,但:

  • 所有类默认继承 object,它有一些基础实现(如 __str__ 返回类名和内存地址)。
  • 容器类(如 listdict)已经实现了全套特殊方法。

回到原题:

选项解析
A. foo 对象表现得像个序列

要成为序列,对象需要同时支持__getitem____len__方法。但在本题中,类Foo并没有定义__len__方法,所以它不符合序列的完整定义。因此,该选项错误

B. 可以使用 len (foo) 来查看对象 foo 的元素个数

由于类Foo没有实现__len__方法,一旦调用len(foo),程序就会抛出TypeError异常。所以,该选项错误

C. 可以使用 for i in foo:print (i) 来遍历 foo 的元素

在 Python 中,当对象没有定义__iter__方法时,for循环会借助__getitem__方法,从索引 0 开始依次尝试获取元素,直至出现IndexError异常。对于Foo类的实例,__getitem__方法能够正常返回range(0, 30, 10)中的元素,所以可以通过for循环进行遍历。因此,该选项正确

D. 不能使用 foo [0] 来访问对象 foo 的第一个元素

Foo类已经实现了__getitem__方法,所以完全可以使用foo[0]来访问元素,并且会返回 0。所以,该选项错误

总结

正确答案是 C。本题的关键在于理解__getitem__方法赋予对象的能力,以及for循环在对象没有实现__iter__方法时的 fallback 机制。在解答这类题目时,要仔细查看类中实现了哪些特殊方法,以及这些方法对应的功能。

建议

遇到这类题目时:

  1. 检查类定义:看实现了哪些特殊方法(如 __getitem____len__)。
  2. 理解方法作用
    • __getitem__ → 支持下标访问和 for 循环。
    • __len__ → 支持 len()
  3. 注意隐含规则for 循环的 fallback 机制是关键。

通过多分析例子,你会逐渐熟悉这些规则!

3 在 Python 中,所有标准对象都可以用于布尔测试

在 Python 中,所有标准对象确实都可以用于布尔测试,字典也不例外。布尔测试的核心是判断对象为 “真”(True)或 “假”(False),具体规则如下:

哪些情况对象会被视为 “假”?

对于标准对象,以下情况在布尔测试中返回 False

  • 常量:NoneFalse
  • 数值:0(整数)、0.0(浮点数)、0j(复数)
  • 空序列 / 集合:空字符串("")、空列表([])、空元组(())、空字典({})、空集合(set())、空范围(range(0)
  • 其他:实现了 __bool__() 方法且返回 False,或实现了 __len__() 方法且返回 0 的对象

字典的布尔测试规则

字典的布尔测试遵循 “空则为假,非空则为真”:

  • 空字典({})→ 布尔值为 False
  • 非空字典(如 {"a": 1})→ 布尔值为 True

python

运行

empty_dict = {}
non_empty_dict = {"name": "Python"}print(bool(empty_dict))      # 输出: False
print(bool(non_empty_dict))  # 输出: True

总结

Python 中所有标准对象(包括字典)都能参与布尔测试,其结果由对象的 “空值” 或 “非空值” 特性决定。字典作为常用的标准对象,空字典被视为 False,非空字典被视为 True,这一规则在条件判断(如 if 语句)中经常用到。

4 在list中添加新元素的方法

在 Python 中,向列表(list)添加新元素有多种方法,每种方法适用于不同的场景。以下是最常用的几种方式及其区别:

1. append():在末尾添加单个元素

  • 语法list.append(element)
  • 特点:将元素直接添加到列表末尾,原地修改列表,返回值为 None

python

运行

fruits = ["apple", "banana"]
fruits.append("cherry")
print(fruits)  # 输出: ['apple', 'banana', 'cherry']

2. extend():在末尾添加多个元素(可迭代对象)

  • 语法list.extend(iterable)
  • 特点:将可迭代对象(如列表、元组、字符串)的元素逐个展开并添加到列表末尾,原地修改列表

python

运行

fruits = ["apple", "banana"]
fruits.extend(["cherry", "date"])  # 添加列表
print(fruits)  # 输出: ['apple', 'banana', 'cherry', 'date']fruits.extend(("elderberry", "fig"))  # 添加元组
print(fruits)  # 输出: ['apple', 'banana', 'cherry', 'date', 'elderberry', 'fig']fruits.extend("grape")  # 添加字符串(会拆分为字符)
print(fruits)  # 输出: ['apple', 'banana', 'cherry', 'date', 'elderberry', 'fig', 'g', 'r', 'a', 'p', 'e']

3. insert():在指定位置插入元素

  • 语法list.insert(index, element)
  • 特点:将元素插入到指定索引位置,原位置及后续元素后移,原地修改列表

python

运行

fruits = ["apple", "banana"]
fruits.insert(1, "cherry")  # 在索引1处插入
print(fruits)  # 输出: ['apple', 'cherry', 'banana']fruits.insert(0, "date")  # 在开头插入
print(fruits)  # 输出: ['date', 'apple', 'cherry', 'banana']

4. + 或 +=:拼接列表

  • +:创建新列表,不修改原列表。
  • +=:等价于 extend(),原地修改列表。

python

运行

# 使用 + 创建新列表
fruits1 = ["apple", "banana"]
fruits2 = ["cherry", "date"]
new_fruits = fruits1 + fruits2
print(new_fruits)  # 输出: ['apple', 'banana', 'cherry', 'date']# 使用 += 原地扩展
fruits1 += fruits2
print(fruits1)  # 输出: ['apple', 'banana', 'cherry', 'date']

5. 切片赋值:替换或插入元素

  • 语法list[start:end] = iterable
  • 特点:可在指定位置替换或插入多个元素,原地修改列表

python

运行

fruits = ["apple", "banana", "cherry"]
fruits[1:2] = ["date", "elderberry"]  # 替换索引1的元素
print(fruits)  # 输出: ['apple', 'date', 'elderberry', 'cherry']fruits[1:1] = ["fig"]  # 在索引1处插入(不替换)
print(fruits)  # 输出: ['apple', 'fig', 'date', 'elderberry', 'cherry']

方法对比表

方法作用是否原地修改接受多个元素?适用场景
append()末尾添加单个元素简单添加单个元素
extend()末尾展开添加可迭代对象添加多个元素(如列表合并)
insert()指定位置插入单个元素在特定位置插入元素
+拼接两个列表创建新列表(不修改原列表)
+=原地扩展列表高效扩展现有列表
切片赋值替换 / 插入元素复杂的批量替换或插入操作

常见错误

  • 误用 append() 添加列表:若直接 append() 一个列表,会将整个列表作为单个元素添加。

python

运行

fruits = ["apple", "banana"]
fruits.append(["cherry", "date"])
print(fruits)  # 输出: ['apple', 'banana', ['cherry', 'date']] (嵌套列表)

正确做法是使用 extend() 或 +=

python

运行

fruits = ["apple", "banana"]
fruits.extend(["cherry", "date"])
print(fruits)  # 输出: ['apple', 'banana', 'cherry', 'date']

总结

根据需求选择合适的方法:

  • 若只需添加单个元素,用 append()
  • 若要添加多个元素(如合并列表),用 extend() 或 +=
  • 若需在特定位置插入,用 insert() 或切片赋值。
  • 若不想修改原列表,用 + 创建新列表。
http://www.dtcms.com/a/301869.html

相关文章:

  • 【unitrix】 6.18 二进制小数特质(t_decimal.rs)
  • EPOLLET 边缘触发模式深度解析
  • 抗辐照芯片在低轨卫星星座CAN总线通讯及供电系统的应用探讨
  • vue3的一些浅显用法
  • Day06–哈希表–242. 有效的字母异位词,349. 两个数组的交集,202. 快乐数,1. 两数之和
  • 浙大公开课—基于深度学习的特征匹配与姿态估计
  • (补题)拼图游戏
  • EPOLLIN事件的详细解析
  • 【时时三省】(C语言基础)指针数组和多重指针
  • MySQL 8.4 Windows 版安装记录与步骤参考
  • 【C语言网络编程基础】DNS 协议与请求详解
  • Context Engineering Notes
  • 持续优化Cypress自动化测试
  • FunctionCall 如何使用以及如何训练
  • 从MySQL的information_schema系统数据库中获取表的元数据信息
  • Dify 1.7.0 新特性解析:工作流革新与多模态能力突破
  • 基于springboot的在线购票系统/在线售票系统
  • WSL切换网络模式
  • 【通识】正则表达式
  • 一些免费的线上学习网站
  • 《前端缓存系统构建:浏览器与Service Worker的自动清理与命中率优化策略》
  • 影刀RPA_初级课程_玩转影刀自动化_网页操作自动化
  • Frontiers in Psychology投稿LaTeX(三)
  • Frontiers in Psychology投稿流程(二)
  • BUG记录——Request接传Json数据中文乱码
  • 2025年7月世界人工智能大会最新消息
  • ABP VNext + Mapster:高性能对象映射
  • C语言——关于指针(逐渐清晰版)
  • MyBatis-Plus 多数据源配置指南
  • Android Framework知识点