Python 基础面试第三弹
1. 获取当前目录下所有文件名
- import os
- def get_all_files(directory):
- file_list = []
#os.walk
返回一个生成器,每次迭代时返回当前目录路径、子目录列表和文件列表- for root, dirs, files in os.walk(directory):
- for file in files:
- file_list.append(os.path.join(root, file))
- return file_list
- # 获取当前目录下的所有文件名
- current_directory = os.getcwd()
- files = get_all_files(current_directory)
- # 打印所有文件名
- for file in files:
- print(file)
2. Python中生成器和迭代器区别
迭代器(Iterator)是一种实现了迭代协议的对象,它必须提供一个__iter__()
方法和一个__next__()
方法。通过调用__iter__()
方法,迭代器可以返回自身,并且通过调用__next__()
方法,迭代器可以依次返回下一个元素,直到没有更多元素时抛出StopIteration
异常。迭代器是一种惰性计算的方式,每次只在需要时生成一个元素,从而节省内存空间。可以使用iter()
函数将可迭代对象转换为迭代器。
生成器(Generator)是一种特殊的迭代器,它使用了更为简洁的语法来定义迭代器。生成器可以通过函数中的yield
关键字来实现,当函数执行到yield
语句时,会暂停执行并返回一个值,保存当前状态,下次调用时从上次暂停的位置继续执行。生成器函数可以像普通函数一样接收参数,并且可以包含循环、条件语句等逻辑。生成器是一种非常方便和高效的迭代器实现方式。
下面是生成器和迭代器的区别总结:
- 语法:生成器使用
yield
关键字来定义,而迭代器需要实现__iter__()
和__next__()
方法。 - 实现:生成器可以使用函数来定义,而迭代器可以由类来实现。
- 状态保存:生成器在
yield
语句处暂停执行并保存当前状态,下次调用时从上次暂停的位置继续执行;迭代器通过内部的状态和指针来保存迭代的位置。 - 简洁性:生成器的语法更加简洁,可以使用普通的函数定义和控制流语句;迭代器需要实现多个特殊方法,代码相对较多。
- 惰性计算:生成器是惰性计算的,每次只在需要时生成一个元素;迭代器也可以实现惰性计算,但需要手动控制。
总之,生成器是一种特殊的迭代器,它提供了更简洁和方便的语法。生成器可以通过函数中的yield
语句来实现迭代过程,并且可以像普通函数一样编写逻辑。迭代器是一种更通用的概念,可以通过类来实现,需要显式地定义__iter__()
和__next__()
方法。无论是生成器还是迭代器,它们都能够实现按需生成和处理大量数据的能力,提高了代码的效率和可读性。
当我们需要遍历一个很大的数据集时,生成器可以帮助我们按需生成数据,而不是一次性加载整个数据集到内存中。
下面是一个简单的例子,我们使用生成器来按需生成斐波那契数列的前n个元素:
- def fibonacci_generator(n):
- a, b = 0, 1
- count = 0
- while count < n:
- yield a
- a, b = b, a + b
- count += 1
- # 使用生成器按需生成斐波那契数列的前10个元素
- fibonacci = fibonacci_generator(10)
- # 逐个打印生成的元素
- for num in fibonacci:
- print(num)
在上述代码中,我们定义了一个生成器函数fibonacci_generator
,它使用了yield
语句来生成斐波那契数列的元素。每次调用生成器的__next__()
方法时,它会执行到yield
语句处,
返回当前的斐波那契数并暂停执行,保存当前状态。然后,下次调用生成器的__next__()
方法时,它会从上次暂停的位置继续执行,生成下一个斐波那契数。这样,我们可以通过迭代生成器
来按需获取斐波那契数列的元素。当我们遍历生成器对象时,它会依次生成斐波那契数列的元素并打印出来。由于生成器是按需生成数据的,它只在需要时生成一个元素,而不是一次性生成整
个数列。这样可以节省内存空间,特别是当斐波那契数列很大时。总结起来,生成器可以看作是一种特殊的函数,它能够按需生成数据,节省内存空间,并且提供了一种简洁和方便的方式来
实现迭代器。通过使用生成器,我们可以避免一次性加载大量数据到内存中,而是在需要时逐个生成数据,从而提高代码的效率和可扩展性。
3. 什么是可迭代对象,其原理又是什么
可迭代对象(Iterable)是指可以被迭代遍历的对象。在许多编程语言中,迭代是指按照一定的顺序逐个访问集合中的元素的过程。在Python中,可迭代对象是指实现了迭代器协议(Iterator Protocol)的对象。
迭代器协议包含两个方法:
__iter__()方法:该方法返回一个迭代器对象。迭代器对象用于实现具体的迭代逻辑,并且必须包含__next__()方法。
__next__()方法:该方法返回迭代器中的下一个元素。如果没有元素可供返回,它应该引发StopIteration异常。
当我们使用可迭代对象进行迭代时,实际上是通过迭代器对象来完成的。迭代器对象负责追踪当前的迭代状态,并提供下一个元素。迭代器对象会在每次迭代时调用__next__()方法,并返回下一个元素,直到遍历完所有元素或者引发StopIteration异常为止。
Python中许多内置的数据类型和容器都是可迭代对象,例如列表(List)、元组(Tuple)、字典(Dictionary)、集合(Set)等。此外,我们也可以通过自定义类来实现可迭代对象,只需在类中定义__iter__()方法,并在该方法中返回一个迭代器对象即可。
以下是一个示例,展示了如何使用可迭代对象和迭代器对象进行迭代:
- # 创建一个可迭代对象
- my_list = [1, 2, 3, 4, 5]
- # 获取迭代器对象
- my_iter = iter(my_list)
- # 使用迭代器对象进行迭代
- try:
- while True:
- item = next(my_iter)
- print(item)
- except StopIteration:
- pass
在上述示例中,我们通过调用iter()
函数获取了my_list
的迭代器对象my_iter
,然后使用next()
函数从迭代器对象中获取下一个元素并打印,直到遍历完所有元素或引发
StopIteration
异常为止。可迭代对象的原理是基于迭代器协议的实现,通过迭代器对象的__next__()方法来提供序列中的下一个元素。这种机制使得我们可以方便地对集合中的元素
进行逐个访问和处理,提供了一种统一的迭代接口
自己实现可迭代对象小栗子
- class MyIterable:
- def __init__(self, data):
- self.data = data
- def __iter__(self):
- self.index = 0
- return self
- def __next__(self):
- if self.index < len(self.data):
- item = self.data[self.index]
- self.index += 1
- return item
- else:
- raise StopIteration
- # 创建一个可迭代对象实例
- my_iterable = MyIterable([1, 2, 3, 4, 5])
- # 使用迭代器进行迭代
- for item in my_iterable:
- print(item)
4. Python2 和 Python3主要的区别有哪些:
Python 2.x 和 Python 3.x 之间的一些主要区别:
打印函数:在 Python 2.x 中,打印语句是一个关键字,使用类似于
print "Hello"
的语法。而在 Python 3.x 中,print
被改造为一个内置函数,需要使用括号,例如print("Hello")
。整数除法:在 Python 2.x 中,整数除法的结果会被截断为整数,例如
5 / 2
的结果是2
。而在 Python 3.x 中,整数除法的结果将保留小数部分,得到浮点数结果,例如5 / 2
的结果是2.5
。如果想要执行截断整数除法,可以使用//
运算符。Unicode 字符串:在 Python 2.x 中,字符串类型分为普通字符串和 Unicode 字符串(以
u
前缀表示),这导致字符串处理的一些混乱和困惑。而在 Python 3.x 中,所有字符串都是 Unicode 字符串,普通字符串是以字节表示的,需要使用b
前缀表示。xrange
替代range
:在 Python 2.x 中,range
函数返回的是一个列表,如果需要生成大范围的整数序列,会占用大量内存。而在 Python 3.x 中,range
函数的实现类似于 Python 2.x 中的xrange
,返回一个迭代器对象,节省了内存。异常语法:在 Python 2.x 中,捕获异常时使用的语法是
except Exception, e
,将异常对象存储在变量e
中。而在 Python 3.x 中,使用except Exception as e
的语法,将异常对象存储在变量e
中。input
函数:在 Python 2.x 中,input
函数会将用户输入的内容作为 Python 代码进行解析,存在安全风险。而在 Python 3.x 中,input
函数始终将用户输入的内容作为字符串返回,不进行解析。
除了上述主要区别之外,Python 3.x 还进行了一些其他改进,包括改进的类定义语法、更好的模块管理和导入机制、更一致的异常处理和错误机制等。然而,这也导致了 Python 2.x 代码无法直接在 Python 3.x 中运行,需要进行一些修改和调整。
5. 说说Python中多线程和多进程
多线程(Multithreading):
- 多线程是指在一个进程内创建多个线程,每个线程独立执行不同的任务。多线程共享进程的内存空间,因此线程之间可以方便地共享数据。
- 在 Python 中,可以使用
threading
模块来创建和管理线程。通过创建Thread
类的实例,指定要执行的函数或方法,并调用start()
方法,可以启动一个线程。 - Python 的多线程由于全局解释器锁(Global Interpreter Lock,GIL)的存在,同一时刻只允许一个线程执行 Python 字节码。这意味着多线程并不能充分利用多核处理器,并发性能受限。多线程适用于 I/O 密集型任务,如网络请求、文件读写等,但对于 CPU 密集型任务,多线程并不能提升性能。
多进程(Multiprocessing):
- 多进程是指创建多个独立的进程,每个进程都有自己的内存空间和系统资源。多个进程之间相互独立,可以并行执行不同的任务。每个进程都有自己的 Python 解释器,因此可以充分利用多核处理器,提高并发性能。
- 在 Python 中,可以使用
multiprocessing
模块来创建和管理进程。通过创建Process
类的实例,指定要执行的函数或方法,并调用start()
方法,可以启动一个进程。 - 多进程可以通过进程间通信(Inter-Process Communication,IPC)来实现进程之间的数据共享。Python 提供了多种 IPC 机制,如队列(Queue)、管道(Pipe)和共享内存等。
总结:
- 多线程适合处理 I/O 密集型任务,可以提高程序的响应能力和效率。
- 多进程适合处理 CPU 密集型任务,可以充分利用多核处理器提高并发性能。
- 在 Python 中,多线程受到 GIL 的限制,多进程可以绕过 GIL,实现真正的并行执行。
- 使用多线程或多进程时需要注意线程安全和进程安全的问题,避免数据竞争和共享资源的冲突。
6. Python中GIL锁:
全局解释器锁(Global Interpreter Lock,简称 GIL)是在 CPython 解释器中存在的一个特性。它是一种机制,用于保证同一时刻只有一个线程执行 Python 字节码。虽然 GIL 的存在确保了 CPython 解释器的线程安全性,但也对多线程并发执行带来了一些限制。
以下是对 GIL 的一些详细解释和理解:
GIL 的作用:
- GIL 的主要作用是保护 CPython 解释器内部的数据结构免受并发访问的影响,确保线程安全。
- CPython 使用引用计数(Reference Counting)作为内存管理的主要机制。GIL 保证了在修改引用计数时的原子性,避免了竞态条件(Race Condition)和内存泄漏问题。
- GIL 还可以简化 CPython 解释器的实现,使其更加简单高效。
GIL 的影响:
- 由于 GIL 的存在,同一时刻只有一个线程可以执行 Python 字节码,其他线程被阻塞。这意味着多线程并不能充分利用多核处理器,无法实现真正的并行执行。
- 对于 CPU 密集型任务,由于 GIL 的限制,多线程并不能提升性能。实际上,由于线程切换的开销,可能导致多线程执行速度比单线程还要慢。
- GIL 对于 I/O 密集型任务的影响相对较小,因为线程在进行 I/O 操作时会主动释放 GIL,允许其他线程执行。因此,多线程在处理 I/O 操作时仍然可以提供一定的性能优势。
解决 GIL 的方法:
- 采用多进程:由于每个进程都有独立的 Python 解释器和 GIL,多进程可以充分利用多核处理器,实现并行执行。
- 使用扩展模块:某些扩展模块,如 NumPy、Pandas 等,使用 C/C++ 编写,可以释放 GIL,允许多线程并行执行。
- 使用多线程库:一些第三方库,如
multiprocessing
模块、concurrent.futures
模块等,提供了替代方案,使得在某些情况下可以绕过 GIL 的限制。
需要注意的是,GIL 只存在于 CPython 解释器中,而其他实现(如 Jython、IronPython)可能没有 GIL。此外,对于许多类型的应用程序,如 I/O 密集型、并发处理不频繁的应用程序,GIL
的影响较小,可以继续使用多线程来实现并发。然而,对于 CPU 密集型任务和需要充分利用多核处理器的应用程序,考虑使用多进程或其他解决方案来规避 GIL。
Python 基础面试第三弹的更多相关文章
- Python基础语法(三)
Python基础语法(三) 1. 数值型数据结构 1.1 要点 在之前的博客也有提到,数值型数据结构在这里就不过多介绍了.在这里提及一些需要知道的知识点. int.float.complex.bool ...
- python基础篇(三)
PYTHON基础篇(三) 装饰器 A:初识装饰器 B:装饰器的原则 C:装饰器语法糖 D:装饰带参数函数的装饰器 E:装饰器的固定模式 装饰器的进阶 A:装饰器的wraps方法 B:带参数的装饰器 C ...
- python基础面试
1 请用自己的算法, 按升序合并如下两个list, 并去除重复的元素: list1 = [2, 3, 8, 4, 9, 5, 6]list2 = [5, 6, 10, 17, 11, 2] 答案: ...
- Python基础面试,看这篇文章画重点吧,Python面试题No1
为什么有这个系列的文章 一直想写一些更加基础的文章,但是总是想不到好的点子,最近到了就业季,一大堆学生面临就业了,正好,从Python的面试题出发,分析和解答一些常见的面试题,并且总结一些文字. 每一 ...
- python基础面试常见题
1.为什么学习Python? Python是目前市面上,我个人认为是最简洁.最优雅.最有前途.最全能的编程语言,没有之一. 2.通过什么途径学习的Python? 通过自学,包括网上查看一些视频,购买一 ...
- Python基础笔记系列三:list列表
本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! python中的list列表是一种序列型数据类型,一有序数据集合用逗号间隔 ...
- python基础实践(三)
-*-列表是新手可直接使用的最强大的python功能之一,它融合了众多重要的编程概念.-*- # -*- coding:utf-8 -*-# Author:sweeping-monkQuestion_ ...
- python基础知识(三)
摘要:主要涉及新数据类型set集合.三元运算.深浅拷贝.函数基础.全局变量与局部变量 一.set --> 无序,不允许重复的集合 不允许重复的列表, 1,创建 s = set() 接收 ...
- Python 基础【第三篇】输入和输出
这里我们创建一个python(pytest)脚本用于学习测试(以后都为这个文件,不多做解释喽),这个文件必须要有执行权限的哈 1.创建pytest并赋予执行权限 [root@fengyuba_serv ...
- python基础教程(三)
序列概览 Python 包含6 种内建的序列,这里重点讨论最常用的两种类型:列表和元组. 列表与元组的主要区别在于,列表可以修改,元组则不能.也就是说如果要根据要求来添加元素,那么列表可以会更好用:而 ...
随机推荐
- 小程序使用echarts 在一个页面打印多个饼图的坑
一.下载echarts微信版 下载地址:https://github.com/ecomfe/echarts-for-weixin 或者直接云盘下载 https://pan.baidu.com/s/1i ...
- super在python 2.7和Python3中的使用
重写是继承机制中的重要内容,对于构造方法尤为重要.构造方法用来初始化新建对象的状态,大多数子类不仅要有自己的初始化代码,还要拥有超类的初始化代码.如果一个类的构造方法被重写,那么就需要调用超类的构造方 ...
- 如何使用 Megatron-LM 训练语言模型
在 PyTorch 中训练大语言模型不仅仅是写一个训练循环这么简单.我们通常需要将模型分布在多个设备上,并使用许多优化技术以实现稳定高效的训练.Hugging Face Accelerate 的创建 ...
- JS逆向实战15——猿人学第五题 动态cookie乱码增强
声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 网站 https://ma ...
- 文心一言 VS 讯飞星火 VS chatgpt (27)-- 算法导论5.1 2题
二.请描述 RANDOM(a,b)过程的一种实现,它只调用 RANDOM(0,1).作为a和b的函数,你的过程的期望运行时间是多少? 文心一言: 假设我们有一个伪随机数生成器,可以生成在[0,1)范围 ...
- JavaWeb编程面试题——导航
引言 面试题==知识点,这里所记录的面试题并不针对于面试者,而是将这些面试题作为技能知识点来看待.不以刷题进大厂为目的,而是以学习为目的.这里的知识点会持续更新,目录也会随时进行调整. 关注公众号:编 ...
- nordic——NCS下的DFU升级(基于NCS)
一.简介 在NCS中有多种的DFU选择,强烈推荐使用MCUboot,当然如果你需要选择传统的nrf_DFU也是可以的,但是要用到官方修改的源文件. 关于mcuboot,原理性的东西在官网和官方博客中有 ...
- JavaWeb中Servlet、web应用和web站点的路径细节("/"究竟代表着什么)
JavaWeb中Servlet.web应用和web站点的路径细节("/"究竟代表着什么) 1 开门见山 新建一个tomcat web项目,配置tomcat的虚拟目录,取默认值(/项 ...
- idea设置退出软件提示
进入设置
- 使用 Transformers 为多语种语音识别任务微调 Whisper 模型
本文提供了一个使用 Hugging Face Transformers 在任意多语种语音识别 (ASR) 数据集上微调 Whisper 的分步指南.同时,我们还深入解释了 Whisper 模型.Com ...