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

学习日志09 python

回家=吃吃吃睡睡睡玩玩玩,好了好了好了,该学学了,脑子不用感觉生锈了。!(其实用了也不太聪明,,,)

囤一下要做的:

  • Python:爬取豆瓣电影 Top250、做一个简单的贪吃蛇游戏(用 pygame)。
  • Java:写一个简易的图书借阅系统(控制台版)、用 Spring Boot 搭一个简单的后端接口。
  • C:实现一个简单的命令行计算器、写一个冒泡排序的可视化程序(用图形库)。

1 python里的update怎么用?

在 Python 中,update() 是一个常用的方法,主要用于更新对象的内容。它在不同的数据类型中有不同的用途和行为。下面介绍几种常见的用法:

1. 字典(dict)的 update() 方法

字典的 update() 方法用于将另一个字典或可迭代对象的键值对更新到当前字典中。

  • 语法dict.update([other])
  • 参数other 可以是字典或包含键值对的可迭代对象。
  • 示例

python

运行

# 创建一个字典
student = {'name': 'Alice', 'age': 20}# 使用另一个字典更新
student.update({'age': 21, 'gender': 'female'})
print(student)  # 输出: {'name': 'Alice', 'age': 21, 'gender': 'female'}# 使用可迭代对象更新(如元组列表)
student.update([('city', 'Beijing'), ('score', 90)])
print(student)  # 输出: {'name': 'Alice', 'age': 21, 'gender': 'female', 'city': 'Beijing', 'score': 90}# 使用关键字参数更新
student.update(id=1001, grade='A')
print(student)  # 输出: {'name': 'Alice', 'age': 21, 'gender': 'female', 'city': 'Beijing', 'score': 90, 'id': 1001, 'grade': 'A'}
  • 注意:如果被更新的键已存在,则会覆盖原有的值;如果不存在,则会添加新的键值对。

2. 集合(set 和 frozenset)的 update() 方法

集合的 update() 方法用于将另一个可迭代对象的元素添加到当前集合中,相当于执行并集操作。

  • 语法set.update(*others)
  • 参数others 可以是一个或多个可迭代对象。
  • 示例

python

运行

# 创建一个集合
s = {1, 2, 3}# 使用另一个集合更新
s.update({3, 4, 5})
print(s)  # 输出: {1, 2, 3, 4, 5}# 使用列表更新
s.update([5, 6, 7])
print(s)  # 输出: {1, 2, 3, 4, 5, 6, 7}# 使用多个可迭代对象更新
s.update((7, 8), {8, 9})
print(s)  # 输出: {1, 2, 3, 4, 5, 6, 7, 8, 9}
  • 注意:集合中的元素具有唯一性,重复的元素会被自动过滤。

3. 其他对象的 update() 方法

一些第三方库或自定义类也可能实现 update() 方法,其行为取决于具体的实现。例如,collections.Counter 类的 update() 方法用于更新计数器:

python

运行

from collections import Counter# 创建一个计数器
count = Counter('abc')
print(count)  # 输出: Counter({'a': 1, 'b': 1, 'c': 1})# 使用另一个计数器更新
count.update(Counter('bcd'))
print(count)  # 输出: Counter({'b': 2, 'c': 2, 'a': 1, 'd': 1})# 使用字符串更新
count.update('cde')
print(count)  # 输出: Counter({'c': 3, 'b': 2, 'a': 1, 'd': 2, 'e': 1})

总结

  • 字典:更新键值对,可覆盖或添加。
  • 集合:添加元素,执行并集操作,自动去重。
  • 其他对象:根据具体实现而定,通常用于更新对象状态。

使用时需注意对象类型和 update() 方法的具体参数要求。

2 python迭代器适合处理大文件

在 Python 中,迭代器(Iterator) 是处理大文件、海量数据或无限序列的核心工具。它允许你逐个访问元素,而不必一次性将整个数据集加载到内存中。下面帮你系统回顾迭代器的相关知识:

一、基本概念:可迭代对象 vs 迭代器

  1. 可迭代对象(Iterable)

    • 任何实现了 __iter__() 方法的对象(如列表、字符串、文件)。
    • 可以用 for 循环遍历,但本身不保存迭代状态。
  2. 迭代器(Iterator)

    • 实现了 __iter__() 和 __next__() 方法的对象。
    • __next__() 方法返回下一个元素,直到没有元素时抛出 StopIteration 异常。
    • 迭代器是一次性消耗品,遍历完后不能重复使用。
  3. 关系

    • 可迭代对象通过 iter() 函数转换为迭代器。
    • 迭代器自身也是可迭代对象(__iter__() 返回自身)。

二、迭代器的核心方法

  1. __iter__()

    • 返回迭代器对象本身(用于 for 循环或 iter() 函数)。
  2. __next__()

    • 返回下一个元素,若没有元素则抛出 StopIteration

示例:手动实现一个简单的迭代器

python

运行

class MyRange:def __init__(self, start, end):self.start = startself.end = endself.current = startdef __iter__(self):return self  # 返回自身作为迭代器def __next__(self):if self.current < self.end:value = self.currentself.current += 1return valueelse:raise StopIteration  # 结束迭代# 使用自定义迭代器
my_range = MyRange(0, 3)
print(next(my_range))  # 输出 0
print(next(my_range))  # 输出 1
print(next(my_range))  # 输出 2
print(next(my_range))  # 抛出 StopIteration

三、为什么处理大文件时迭代器是最优选择?

内存效率高

  • 文件对象是天然的迭代器,逐行读取不占内存。
  • 示例:处理 10GB 大文件,传统读取 vs 迭代器读取

python

运行

# 传统方法(一次性加载,可能内存溢出)
with open('large_file.txt') as f:lines = f.readlines()  # 全部读入内存for line in lines:print(line)# 迭代器方法(逐行读取,内存占用恒定)
with open('large_file.txt') as f:for line in f:  # 文件对象本身就是迭代器print(line)  # 每次只处理一行

四、常用的迭代器工具

  1. 生成器(Generator)

    • 特殊的迭代器,用函数 +yield 关键字实现。
    • 示例:生成斐波那契数列

    python

    运行

    def fib_generator():a, b = 0, 1while True:yield a  # 暂停执行并返回当前值a, b = b, a + bfib = fib_generator()
    print(next(fib))  # 0
    print(next(fib))  # 1
    print(next(fib))  # 1
    
  2. 内置迭代器函数

    • iter(iterable):将可迭代对象转换为迭代器。
    • next(iterator[, default]):获取下一个元素,可指定默认值避免异常。
  3. 标准库工具

    • itertools 模块:提供各种高效迭代器(如 countcyclechainislice)。

      python

      运行

      from itertools import islice# 读取文件前10行
      with open('large_file.txt') as f:first_10_lines = islice(f, 10)for line in first_10_lines:print(line)
      

五、处理大文件的进阶技巧

  1. 逐块读取二进制文件

    python

    运行

    with open('large_binary_file.bin', 'rb') as f:while chunk := f.read(4096):  # 每次读取4KBprocess_chunk(chunk)
    
  2. 自定义迭代器处理非标准格式
    例如处理按特定分隔符分块的文件:

    python

    运行

    class ChunkIterator:def __init__(self, file, separator):self.file = fileself.separator = separatordef __iter__(self):return selfdef __next__(self):chunk = []for line in self.file:chunk.append(line)if self.separator in line:return ''.join(chunk)if not chunk:raise StopIterationreturn ''.join(chunk)# 使用自定义迭代器按块读取
    with open('log_file.log') as f:for chunk in ChunkIterator(f, 'END_OF_RECORD'):process_chunk(chunk)
    

六、迭代器 vs 生成器 vs 列表推导式

特性列表推导式生成器表达式手动迭代器
语法[x for x in iterable](x for x in iterable)类 +__iter__+__next__
内存占用高(一次性生成所有元素)低(按需生成)低(按需生成)
是否可重复使用
适用场景小数据量、需要多次遍历大数据量、一次性遍历复杂状态管理、自定义逻辑

七、常见面试题

  1. 手写一个迭代器,实现 range(start, stop, step) 功能

    python

    运行

    class MyRange:def __init__(self, start, stop, step=1):self.start = startself.stop = stopself.step = stepself.current = startdef __iter__(self):return selfdef __next__(self):if (self.step > 0 and self.current >= self.stop) or \(self.step < 0 and self.current <= self.stop):raise StopIterationvalue = self.currentself.current += self.stepreturn value
    
  2. 如何判断一个对象是否是迭代器?

    python

    运行

    from collections.abc import Iteratorobj = iter([1, 2, 3])
    print(isinstance(obj, Iterator))  # True
    

  3. 处理大文件时,readlines() 和直接迭代文件对象的区别?

    • readlines():一次性读取所有行到列表,内存占用高。
    • 直接迭代:逐行读取,内存占用恒定。

八、总结

  1. 核心优势:节省内存,适合处理无限序列或大文件。
  2. 使用场景:大数据处理、流式计算、无限序列(如随机数生成)。
  3. 最佳实践
    • 优先用生成器表达式(简洁)。
    • 复杂逻辑用 yield 实现生成器函数。
    • 超大文件用 read(size) 按块读取。

掌握迭代器,你就能优雅地处理 GB 级数据,而不用担心内存溢出的问题!如果需要进一步练习,可以尝试用迭代器实现一个大文件的词频统计功能。

3 python有关文件的读取

在 Python 中,文件读取是数据处理的基础操作。结合迭代器的特性,下面系统整理文件读取的核心语法、最佳实践及进阶技巧:

一、基础文件操作:打开、读取、关闭

1. 打开文件:open() 函数

python

运行

file = open('filename.txt', mode='r', encoding='utf-8')
  • 模式参数 mode

    • 'r':读取(默认)
    • 'w':写入(覆盖)
    • 'a':追加
    • 'b':二进制模式(与其他模式组合,如 'rb'
    • '+':读写模式(如 'r+'
  • 编码参数 encoding
    推荐显式指定(如 'utf-8'),避免中文等非 ASCII 字符乱码。

2. 读取文件内容

python

运行

# 一次性读取全部内容(小文件适用)
content = file.read()  # 字符串# 读取指定字节数
first_10_bytes = file.read(10)  # 读取前10个字节# 按行读取(返回列表)
lines = file.readlines()  # ['line1\n', 'line2\n', ...]# 逐行读取(迭代器方式,大文件推荐)
for line in file:process(line)
3. 关闭文件

python

运行

file.close()  # 手动关闭# 推荐用 with 语句(自动管理资源)
with open('filename.txt', 'r') as file:content = file.read()
# 离开 with 块时,文件自动关闭

二、大文件读取的最佳实践

1. 逐行读取(内存效率最高)

python

运行

with open('large_file.txt') as f:for line in f:  # 文件对象是天然的迭代器process(line)  # 每次处理一行
2. 按块读取(二进制文件)

python

运行

CHUNK_SIZE = 4096  # 4KB
with open('data.bin', 'rb') as f:while chunk := f.read(CHUNK_SIZE):  # Python 3.8+ 海象运算符process(chunk)
3. 读取前 N 行

python

运行

from itertools import islicewith open('large_file.txt') as f:first_10_lines = islice(f, 10)  # 读取前10行for line in first_10_lines:print(line)

三、文件读取进阶技巧

1. 处理非标准分隔符的文件

python

运行

def read_in_chunks(file_obj, separator):"""按自定义分隔符读取文件块"""buffer = ""for line in file_obj:buffer += lineif separator in buffer:chunks = buffer.split(separator)for chunk in chunks[:-1]:yield chunk + separatorbuffer = chunks[-1]if buffer:yield buffer# 使用示例
with open('log.txt') as f:for chunk in read_in_chunks(f, 'END'):process_chunk(chunk)
2. 跳过文件头部或尾部

python

运行

with open('data.csv') as f:# 跳过标题行next(f)  # 直接调用 next() 跳过第一行# 处理数据行for line in f:process_data(line)
3. 同时读取多个文件

python

运行

with open('file1.txt') as f1, open('file2.txt') as f2:for line1, line2 in zip(f1, f2):# 并行处理两个文件的同一行process(line1, line2)

四、文件解析工具

1. CSV 文件

python

运行

import csvwith open('data.csv', newline='') as f:reader = csv.reader(f)for row in reader:print(row)  # 每行为列表# 带标题的 CSV
with open('data.csv', newline='') as f:reader = csv.DictReader(f)for row in reader:print(row['column_name'])  # 按列名访问
2. JSON 文件

python

运行

import jsonwith open('data.json') as f:data = json.load(f)  # 解析为字典/列表for item in data:process(item)
3. XML 文件

python

运行

import xml.etree.ElementTree as ETtree = ET.parse('data.xml')
root = tree.getroot()for child in root:print(child.tag, child.attrib)

五、常见错误处理

1. 文件不存在

python

运行

try:with open('nonexistent.txt') as f:content = f.read()
except FileNotFoundError:print("文件不存在,请检查路径!")
2. 权限错误

python

运行

try:with open('/etc/passwd', 'w') as f:  # 尝试写入系统文件f.write('data')
except PermissionError:print("没有权限操作该文件!")
3. 编码错误

python

运行

try:with open('file.txt', encoding='utf-8') as f:content = f.read()
except UnicodeDecodeError:print("文件编码可能不是 UTF-8,尝试其他编码...")

六、性能优化

1. 读取 vs 解析分离

python

运行

# 低效:边读取边解析
with open('data.csv') as f:for line in f:parts = line.strip().split(',')  # 每行都执行 split# 高效:批量解析
with open('data.csv') as f:lines = f.readlines()  # 一次性读取所有行parsed_data = [line.strip().split(',') for line in lines]
2. 使用生成器处理超大文件

python

运行

def process_large_file(filename):with open(filename) as f:for line in f:yield process_line(line)  # 逐行处理并生成结果# 使用生成器
for result in process_large_file('huge_data.txt'):save_result(result)

七、面试高频问题

1. 如何高效读取 10GB 大文件?
  • 用迭代器逐行读取(for line in file
  • 按块读取(read(CHUNK_SIZE)
  • 避免使用 readlines() 一次性加载
2. 如何在不加载整个文件的情况下获取文件行数?

python

运行

count = 0
with open('large_file.txt') as f:for _ in f:  # 逐行迭代但不处理内容count += 1
print(f"文件行数: {count}")
3. 如何实现文件的倒序读取?

python

运行

from collections import dequedef tail(filename, n=10):"""获取文件最后 n 行(类似 Linux tail 命令)"""with open(filename) as f:return deque(f, n)  # deque 的 maxlen 参数自动保留最后 n 个元素print(tail('data.log', 5))  # 获取最后 5 行

八、总结

场景推荐方法示例代码
小文件读取read() 或 readlines()with open('file.txt') as f: content = f.read()
大文件逐行处理迭代器方式with open('large.txt') as f: for line in f: ...
二进制文件分块读取read(CHUNK_SIZE)while chunk := f.read(4096): process(chunk)
CSV 文件解析csv.reader 或 csv.DictReaderwith open('data.csv') as f: reader = csv.DictReader(f)
JSON 文件解析json.load()with open('data.json') as f: data = json.load(f)

掌握这些技巧后,你可以高效处理从几 KB 到几十 GB 的各种文件,同时避免内存溢出的风险。

4 在 Python的命名规范中有关单下划线(_)和双下划线(__

在 Python 里,命名规范借助单下划线(_)和双下划线(__)来体现变量、方法或者类的特殊用途和可见性。下面详细介绍各类命名方式及其使用场景:

1. 单前导下划线(例如 _var

这一命名方式用于表明某个变量或者方法是 “内部使用” 的。虽然 Python 不会强制限制访问,但按照惯例,它不应该被外部直接调用。这种方式常见于模块、类或者函数内部的私有元素。

python

运行

class MyClass:def __init__(self):self._internal_var = 42  # 内部变量,外部不应直接访问def _internal_method(self):  # 内部方法,外部不应直接调用pass

2. 单末尾下划线(例如 var_

当某个变量名与 Python 内置关键字冲突时,会采用这种命名方式。这样做是为了避免命名冲突。

python

运行

def my_function(class_):  # 使用 class_ 避免与内置关键字 class 冲突pass

3. 双前导下划线(例如 __var

这是一种 “名称修饰” 机制。在类中使用双前导下划线命名的属性或者方法,会自动将名称修改为 _ClassName__var,以此来避免子类意外覆盖该名称。

python

运行

class Parent:def __init__(self):self.__private_var = 10  # 名称会被修饰为 _Parent__private_varclass Child(Parent):def __init__(self):super().__init__()self.__private_var = 20  # 名称会被修饰为 _Child__private_varprint(Child()._Parent__private_var)  # 输出 10
print(Child()._Child__private_var)  # 输出 20

4. 双前导和双末尾下划线(例如 __var__

这类名称被称为 “魔术方法” 或者 “特殊方法”,是 Python 内置的特殊方法,像 __init____str____len__ 等都属于此类。我们应该避免自己定义这类名称,而是按照 Python 的约定去使用它们。

python

运行

class MyClass:def __init__(self, value):  # 初始化方法self.value = valuedef __str__(self):  # 字符串表示方法return f"MyClass({self.value})"

5. 单下划线(例如 _

在以下几种场景中会使用单下划线:

  • 在交互式解释器里,_ 会存储上一次执行的表达式结果。
  • 用于忽略某些变量的值,也就是作为 “占位符”。
  • 在国际化(i18n)的场景中,_ 常被用作翻译函数名。

python

运行

x, _, y = (1, 2, 3)  # 忽略中间的值
for _ in range(3):  # 不需要使用循环计数器print("Hello")

总结

命名方式示例用途
单前导下划线_var内部使用(惯例)
单末尾下划线var_避免与 Python 关键字冲突
双前导下划线__var类私有成员,通过名称修饰防止子类覆盖
双前导双末尾下划线__var__Python 内置的特殊方法(魔术方法)
单下划线_临时变量、占位符或存储上一次的结果

最佳实践建议

  • 对于内部使用的变量和方法,推荐使用单前导下划线(_var)。
  • 只有当确实需要防止子类覆盖某个名称时,才使用双前导下划线(__var)。
  • 除非是实现特殊方法,否则不要使用双前导双末尾下划线(__var__)。
  • 单下划线(_)要谨慎使用,避免在函数或者类中用它来命名重要的变量。

遵循这些命名规范,能够让你的代码更加清晰易读,同时也能避免一些常见的编程陷阱。

5 Python 中列表的sort方法、自定义排序函数以及字符串切片操作

这个题目主要考察 Python 中列表的sort方法、自定义排序函数以及字符串切片操作。下面为你详细分析:

代码分析

  1. 列表定义

python

运行

lis = ['apple', 'lemon', 'pear', 'peach']

这里创建了一个包含四个水果名称的列表。

  1. 自定义排序函数

python

运行

def fn(x):return x[::-1]

此函数接收一个字符串作为参数,通过切片操作[::-1]将字符串反转后返回。例如,fn('apple')会返回'elppa'

  1. 列表排序

python

运行

lis.sort(key=fn, reverse=True)
  • key=fn:表示按照每个元素经过fn函数处理后的结果进行排序。也就是对每个字符串先反转,再依据反转后的字符串进行排序。
  • reverse=True:意味着按照降序排列。
  1. 输出结果

python

运行

print(lis)

最终会打印出排序后的列表。

具体排序过程

首先,对列表中的每个字符串进行反转:

  • 'apple'反转后是'elppa'
  • 'lemon'反转后是'nomel'
  • 'pear'反转后是'raep'
  • 'peach'反转后是'hcaep'

然后,按照反转后的字符串进行降序排序。在 Python 中,字符串的排序是基于字典序的,降序排序就是从大到小排列。反转后的字符串降序排列为:

  1. 'raep'(对应原字符串'pear'
  2. 'nomel'(对应原字符串'lemon'
  3. 'hcaep'(对应原字符串'peach'
  4. 'elppa'(对应原字符串'apple'

所以,原列表排序后的结果是:

python

运行

['pear', 'lemon', 'peach', 'apple']

考察的知识点

  1. 列表排序:考生需要掌握列表的sort方法,清楚keyreverse参数的用法。
  2. 函数作为参数:要理解可以将函数作为参数传递给sort方法,用于自定义排序规则。
  3. 字符串切片:要明白[::-1]这种切片操作能够实现字符串的反转。
  4. 字典序排序:要知道 Python 中字符串排序是基于字典序的,并且清楚升序和降序的区别。

答案

执行该程序,输出结果为:

python

运行

['pear', 'lemon', 'peach', 'apple']
http://www.dtcms.com/a/279417.html

相关文章:

  • 【SVN】SVN 客户端的安装与操作
  • 设计模式之代理模式:掌控对象访问的优雅之道
  • CVE-2017-7525源码分析与漏洞复现(Jackson 反序列化)
  • Android 中 实现格式化字符串
  • vue2/3生命周期使用建议
  • TCL在芯片设计与验证中的应用实践
  • WinUI3开发_Combobox实现未展开时是图标下拉菜单带图标+文字
  • ConcurrentHashMap 原子操作详解:computeIfAbsent、computeIfPresent和putIfAbsent
  • 技术人生——第12集:思想为王,功能在后
  • (5)LangGraph4j框架ReActAgent实现
  • mit6.5840-lab4C-Snapshot-25Summer
  • Java Stream流详解
  • 文心一言 4.5 开源深度剖析:中文霸主登场,开源引擎重塑大模型生态
  • C++11 std::is_permutation:从用法到原理的深度解析
  • 什么是延迟双删
  • 算法训练营day18 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先
  • 通过 ip a 查看网络接口名
  • 【算法】贪心算法:摆动序列C++
  • 2025js——面试题(8)-http
  • Linux 系统下的 Sangfor VDI 客户端安装与登录完全攻略 (CentOS、Ubuntu、麒麟全线通用)
  • 程序跑飞是什么?
  • 核电概念盘中异动,中核科技涨停引领板块热度
  • 物联网技术促进能量收集创新应用落地
  • 第一章编辑器开发基础第一节绘制编辑器元素_4输入字段(4/7)
  • 【一维 前缀和+差分】
  • 互斥锁与同步锁
  • IIS错误:Service Unavailable HTTP Error 503. The service is unavailable.
  • Unity Shader 预热与缓存优化
  • Unity中HumanBodyBones骨骼对照
  • 卡在“pycharm正在创建帮助程序目录”