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

学习日志36 python

1 lambda 表达式可以作为函数的参数进行传递

在 Python 中,lambda 表达式可以作为函数的参数进行传递。

lambda 表达式本质上创建了一个匿名函数对象,而函数对象在 Python 中是可以作为参数传递的。这在很多场景下非常有用,比如在高阶函数中使用。

例如,在sorted()函数中可以使用 lambda 作为key参数:

python

运行

# 对列表中的元组按第二个元素排序
my_list = [(1, 3), (4, 1), (2, 5)]
sorted_list = sorted(my_list, key=lambda x: x[1])
print(sorted_list)  # 输出 [(4, 1), (1, 3), (2, 5)]

再比如在map()函数中使用 lambda:

python

运行

numbers = [1, 2, 3, 4]
squared = list(map(lambda x: x**2, numbers))
print(squared)  # 输出 [1, 4, 9, 16]

这些例子都证明了 lambda 表达式完全可以作为函数参数传递,这也是 lambda 表达式的常见用法之一。

2 python不支持char数据类型

【py里面不是有char方法吗(这里更正一下其实是chr方法),就是和ord对应的那个,但是为什么不支持char数据类型,str也可以吗,char我的理解就是单个字符与unicode编码对应的数据类型】

在 Python 中,确实没有专门的char数据类型,单个字符在 Python 中依然被视为str类型(字符串),只是长度为 1 而已。这与其他一些编程语言(如 Java、C++)严格区分charString类型的设计不同。

不过,你提到的与ord()对应的函数是chr(),它们的功能如下:

  • ord(c):接收一个长度为 1 的字符串(单个字符),返回对应的对应的它对应的 Unicode 编码值(整数)
  • chr(i):接收一个 Unicode 编码值(整数),返回对应的它对应的字符串形式(单个字符,类型为str

示例:

python

运行

# ord():字符转编码
print(ord('A'))   # 输出:65
print(ord('中'))  # 输出:20013# chr():编码转字符
print(chr(65))    # 输出:'A'(类型是str)
print(chr(20013)) # 输出:'中'(类型是str)

虽然 Python 没有char类型,但长度为 1 的str完全承担了 “单个字符” 的角色,并且能与ord()/chr()完美配合处理 Unicode 编码转换。这种设计简化了 Python 的类型系统,同时也不影响字符与编码的对应操作。

【我的表述中存在一些小的不准确之处】

你的表述中存在一些小的不准确之处,主要体现在对 Python 数据类型的理解上:

  1. 关于char方法:Python 中并没有char()方法,对应的应该是chr()方法(你后面补充说明时纠正了这一点,是正确的)。

  2. 关于char数据类型:你的理解中提到 “char 数据类型”,但如前所述,Python 确实没有专门的char类型,单个字符在 Python 中仍属于str类型(只是长度为 1 的字符串)。这一点与 C、Java 等语言不同,那些语言会严格区分char(单个字符)和字符串类型。

  3. 关于功能对应:你提到 “char 和 ord 对应的那个” 是正确的,chr()ord()确实是一对互逆的函数,分别实现 Unicode 编码到字符、字符到 Unicode 编码的转换,且它们操作的都是长度为 1 的str对象(在 Python 中承担了 “单个字符” 的角色)。

总结来说,核心的误解在于对 Python 是否有char类型的判断,以及对应的函数名称(chr()而非char()),但你对 “单个字符与 Unicode 编码对应” 的理解是正确的。

【其实也不是很难理解,就是体现了py的简洁特性,有一个str就够了,而c和java这些强类型语言更加严谨,对数据类型定义要求严格】

这确实体现了不同编程语言的设计哲学差异:

Python 作为动态类型语言,追求简洁和易用性,用统一的str类型处理所有文本数据(无论是单个字符还是长字符串),减少了类型定义的负担,让开发者更专注于业务逻辑。

而 C、Java 等静态强类型语言则更强调类型的严谨性,通过区分char和字符串类型,在编译阶段就能进行更严格的类型检查,这在大型项目中有助于减少类型相关的错误,也更符合底层内存管理的逻辑(比如char通常占用 1 字节,而字符串是字符数组)。

两种设计各有优劣,Python 的 approach 降低了入门门槛,提升了开发效率;而强类型语言的设计则在代码健壮性和性能优化上有优势。这种差异也让它们在不同场景下各有所长。

3 生成器(次抛)

在Python3.x环境下,执行以下程序,下列说法中,正确的是( )
s = (i for i in range(1, 3))    # ①
print(s.__next__())             # ②
for i in s:print(i)                    # ③
A 语句①的s是一个元组
B 语句②的输出结果为1
C 语句③的输出结果为1 2
D 语句③可以替代为
while s.__next__():print(s.__next__())

这道题考查的是 Python 中的生成器(generator)概念,看起来复杂其实不难,我们一步步来分析:

首先理解每个语句的作用

语句①:s = (i for i in range(1, 3))

这不是元组(元组是(1,2,3)这种直接写值的形式),而是生成器表达式,会创建一个生成器对象。
生成器的特点是:它不会一次性生成所有数据,而是 "按需生成",每次调用才会产生下一个值(节省内存)。
这里的生成器会依次产生 12(因为range(1,3)包含 1 和 2)。

语句②:print(s.__next__())

__next__()是生成器的方法,作用是 "获取生成器的下一个值"。
对于刚创建的生成器s,第一次调用__next__()会得到第一个值 1,所以这句的输出是1

语句③:循环遍历生成器

当生成器已经通过__next__()取过第一个值(1)后,剩下的值只有2了。
所以 for 循环会获取剩下的2并打印,因此语句③的输出是2

分析选项

  • A 选项:错误。语句①的s是生成器,不是元组(元组的定义是直接放元素,如(1,2))。
  • B 选项:正确。语句②第一次调用__next__(),会输出第一个值1
  • C 选项:错误。语句③只能输出剩下的2(因为 1 已经被语句②②取走了)。
  • D 选项:错误。while s.__next__(): 这种写法有两个问题:
    1. 生成器取完所有值后,再调用__next__()会报错(StopIteration),循环无法正常结束;
    2. 即使不报错,每次循环会调用两次__next__(),导致跳过值。

总结

正确答案是 B
生成器的核心是 "边用边生成",每调用一次__next__()就会消耗一个值,这也是为什么语句③只能输出2的原因。

【次抛的生成器,对之前生成的值没有印象】

你这个形容很形象!生成器确实像 "一次性" 的迭代器,它的工作方式就是 "生成一个,输出一个,然后就忘了这个",不会保留已经生成过的值,也不能回头重新获取之前的值。

这种特性叫做 "惰性计算" 或 "流式处理",好处是:

  1. 节省内存:不需要把所有数据都存起来,特别适合处理大量数据或无限序列
  2. 提高效率:用到的时候才生成,不用提前准备好所有值

比如你例子中的生成器:

  • 第一次调用__next__(),生成 1 并返回,之后生成器内部就 "忘记"1 了
  • 第二次获取时,直接生成 2 并返回
  • 再想获取第三个值,就会报错(因为 range (1,3) 只有 1 和 2)

这和列表这种 "一次性生成所有值并保存" 的类型完全不同。如果是列表[1,2],你可以随时通过索引[0]重新获取 1,但生成器做不到这一点。

所以生成器更适合 "用完即弃" 的场景,而不适合需要反复访问数据的场景,这也是它设计上的特点。

集合中的元素顺序

【集合中的元素顺序是随机的??(nowcoder刷题有如是解析)】

在 Python 中,集合(set)的元素不是 “随机” 的,但也不保证有固定顺序,核心原因和它的底层实现(哈希表)有关,我们分 3 点讲透:

1. 先明确:集合的 “无序”≠“随机”

“随机” 是指每次运行结果都可能不一样,但集合的元素顺序有两个关键特点:

  • 相对稳定:在 Python 3.7 + 版本中,只要集合的元素不变、且没有发生 “扩容”(比如新增元素导致哈希表重新排列),每次打印 / 遍历的顺序会保持一致;
  • 不按插入顺序:它不会像列表(list)那样 “先插的在前、后插的在后”,顺序由元素的哈希值(可以理解为元素的 “身份编码”)决定 —— 哈希值会决定元素在哈希表中的存储位置,遍历集合时会按这个位置顺序读取。

比如:

python

运行

s = {3, 1, 2}
print(s)  # 可能输出 {1,2,3}(而非插入顺序3,1,2),且每次运行结果相同

2. 为什么会有 “无序” 的感觉?

因为哈希表的存储规则导致:

  • 元素的存储位置由自身的哈希值计算得出,这个位置和 “插入顺序” 无关;
  • 当集合新增 / 删除元素时,如果触发哈希表 “扩容”(比如空间不够用),所有元素会重新计算位置,此时遍历顺序可能会变 —— 但这种变化是 “按规则改变”,不是 “随机改变”。

3. 对比:有序集合(OrderedDict已过时,用dict替代)

如果你需要 “既去重(集合特性)又保序”,Python 3.7 + 的普通字典(dict 可以替代(因为 3.7 + 的dict保证插入顺序),或者用collections模块的OrderedDict(早期版本用,现在必要性不大):

python

运行

# 用dict实现“保序去重”(键存元素,值随意)
ordered_set = dict.fromkeys([3, 1, 2, 1])  # 键是3,1,2(去重),顺序和插入一致
print(list(ordered_set.keys()))  # 输出 [3,1,2](严格按插入顺序)

总结

  • 结论:集合(set)的元素顺序不是随机的,而是由元素哈希值决定的 “哈希顺序”,且不保证固定(可能因增删元素 / 扩容变化);
  • 关键区分
    • 列表(list):保证插入顺序;
    • 集合(set):无固定顺序(按哈希值排列);
    • 字典(dict,3.7+):保证插入顺序,可替代 “有序集合”。

【是不是一个set我打印两遍会发现元素顺序不一样?】

在 Python 中,大多数情况下,同一个不变的 set 打印两遍,元素顺序是一样的,但存在特殊情况会导致顺序变化,核心取决于 set 的 “底层哈希表是否发生变动”。我们分两种场景说清楚:

1. 场景 1:set 创建后,没有任何增删操作(元素和大小不变)

这种情况下,两次打印顺序完全一致
因为 set 的元素顺序由 “元素的哈希值” 决定 —— 哈希值是元素的固定 “身份编码”(比如整数 1 的哈希值永远是 1,字符串 "a" 的哈希值也固定),只要元素不变,它们在哈希表中的存储位置就不变,遍历 / 打印时就会按相同顺序读取。

示例(Python 3.7+):

python

运行

s = {3, 1, 2, "a"}
print(s)  # 第一次打印,比如输出 {1, 2, 3, 'a'}
print(s)  # 第二次打印,结果和第一次完全一样

2. 场景 2:set 创建后,执行了增删元素的操作(可能触发 “哈希表扩容”)

这种情况下,两次打印顺序可能不一样
因为 set 的底层是 “哈希表”:当你新增元素时,如果哈希表现有空间不够用(比如使用率达到阈值),就会触发 “扩容”—— 此时所有元素会重新计算在新哈希表中的位置,存储位置变了,后续遍历 / 打印的顺序就可能和之前不同。

示例:

python

运行

s = {3, 1, 2}
print(s)  # 第一次打印,假设输出 {1, 2, 3}# 新增元素,触发哈希表扩容(具体是否扩容取决于初始空间,这里仅为示例)
s.add(4)
s.remove(3)  # 再删除一个元素
print(s)  # 第二次打印,可能输出 {1, 4, 2}(顺序和第一次不同)

关键总结

  • 不是 “每次打印都不一样”:不变的 set 打印多次,顺序稳定;
  • 顺序变化的本质:不是 “随机”,而是 “哈希表扩容 / 元素位置重排” 导致的规则性变化;
  • 核心结论:set 不保证 “固定顺序”(可能因操作变动),但也不是 “随机顺序”(变动有规则,不变则稳定)。

如果你需要 “打印顺序绝对固定”,就不能用 set,而应该用 Python 3.7+ 的普通字典(dict,保证插入顺序)来模拟 “有序去重”。

http://www.dtcms.com/a/336438.html

相关文章:

  • 力扣经典算法篇-52-零钱兑换(动态规划)
  • Java语法进阶之常用类
  • 【C2000】德州仪器C2000产品整体介绍
  • http工作流程
  • LangChain 多任务应用开发
  • matlab tlc的文件、字符串操作
  • Python @staticmethod 装饰器与 staticmethod() 函数
  • Tomcat Session Replication Cluster:实现高可用性和可扩展性的关键
  • 机试备考笔记 14/31
  • Ugit使用记录
  • Next.js跟React关系(Next.js是基于React库的全栈框架)(文件系统路由、服务端渲染SSR、静态生成SSG、增量静态再生ISR、API路由)
  • 提升 LLM 推理效率的秘密武器:LM Cache 架构与实践
  • Pandas初学者入门
  • C语言中回调函数的作用
  • 2025.8.11-2025.8.17第33周:完成第一次头马备稿演讲
  • 北京JAVA基础面试30天打卡12
  • 【URP】[法线贴图]为什么主要是蓝色的?
  • ZipList优缺点总结
  • leetcode_438 找到字符串中的所有异位词
  • 代码随想录刷题Day34
  • 上位机知识篇---静态库
  • 计算机网络 TCP 延迟确认机制
  • SpringCloud 01 分布式系统
  • 自由学习记录(85)
  • 【k8s、docker】Headless Service(无头服务)
  • 如何提高目标检测模型在小目标检测任务上的性能
  • 海洋牧场助力可持续发展,保护海洋生态平衡
  • CF2121A Letter Home
  • python pandas库 series如何使用
  • DNS总结