1. 只有4G内存,如何读取一个5G的大文件?
例如复制一个1G的电影为例,复制11111.mp4到22222.mp4
方法一:with open + for循环迭代
- 对可迭代对象 f,进行迭代遍历:for line in f,会自动地使用缓冲IO(buffered IO)以及内存管理,而不必担心任何大文件的问题。
import time
start = time.time()
with open('22222.mp4', 'wb') as f:
with open('11111.mp4', 'rb') as f1:
for line in f1:
f.write(line)
print(time.time()-start)
时间:4.368007659912109 s
方法二:open() + read(size)
- 指定每次读取的大小
import time
start = time.time()
with open('22222.mp4', 'wb') as f:
f1 = open('11111.mp4', 'rb')
while 1:
line = f1.read(100*1024)
if line:
f.write(line)
else:
break
print(time.time()-start)
时间:1.248002052307129 s
方法三:open() + readline()
- 每次按行读取写入
import time
start = time.time()
with open('22222.mp4', 'wb') as f:
f1 = open('11111.mp4', 'rb')
while 1:
line = f1.readline()
if line:
f.write(line)
else:
break
print(time.time()-start)
时间:4.820408344268799 s
方法四:
- 可以通过linux命令split切割成小文件,然后再对数据进行处理,此方法效率比较高。可以按照行数切割,可以按照文件大小切割。
2.os库的操作
os.getcwd() 得到当前工作的目录。
os.listdir() 指定所有目录下所有的文件和目录名,以列表的形式全部列举出来,其中没有区分目录和文件
os.mkdir() 创建目录,注意:这样只能建立一层,要想递归建立可用:os.makedirs()
os.rmdir() 删除指定目录
os.remove() 删除指定文件
os.path.isfile() 判断指定对象是否为文件。是返回True,否则False
os.path.isdir() 判断指定对象是否为目录。是True,否则False
os.path.exists() 检验指定的对象是否存在。是True,否则False
os.path.split() 返回路径的目录和文件名。
os.system() 执行shell命令。例如os.system(“echo ‘hello world’”)
os.chdir() 改变目录到指定目录
os.path.join(path, name) 连接目录和文件名
os.path.getsize() 获得文件的大小,如果为目录,返回0
os.path.basename(path) 返回文件名
os.path.abspath() 获得绝对路径。
os.path.dirname(path) 返回文件路径
参考:https://www.cnblogs.com/liutongqing/p/7499033.html
3.常用的python标准库
os:操作系统接口
sys:命令行参数,通用工具脚本经常调用命令行参数。这些命令行参数以链表形式存储于 sys 模块的 argv 变量。例如在命令行中执行 “python demo.py one two three
” 后可以得到以下输出结果:
import sys
print(sys.argv)
# ['demo.py', 'one', 'two', 'three']
re:字符串正则匹配
math:为浮点运算提供了对底层C函数库的访问
random:提供了生成随机数的工具。
time,datetime:为日期和时间处理同时提供了简单和复杂的方法。
常用时间处理方法:
今天 today = datetime.date.today()
昨天 yesterday = today - datetime.timedelta(days=1)
上个月 last_month = today.month - 1 if today.month - 1 else 12
当前时间戳 time_stamp = time.time()
时间戳转datetime datetime.datetime.fromtimestamp(time_stamp)
datetime转时间戳 int(time.mktime(today.timetuple()))
datetime转字符串 today_str = today.strftime("%Y-%m-%d")
字符串转datetime today = datetime.datetime.strptime(today_str, "%Y-%m-%d")
补时差 today + datetime.timedelta(hours=8)
timeit:性能度量
urllib:发网络请求
threading:线程
multiprocessing:进程
4.对python语言的看法,比如python的优缺点
优点:
1.简单易懂易上手:Python的定位是“优雅”、“明确”、“简单”,所以Python程序看上去总是简单易懂,初学者学Python,不但入门容易,而且将来深入下去,可以编写那些非常非常复杂的程序。
2.开发效率快:开发效率非常高,Python有非常强大的第三方库,基本上你想通过计算机实现任何功能,Python官方库里都有相应的模块进行支持,直接下载调用后,在基础库的基础上再进行开发,大大降低开发周期,避免重复造轮子。
3.高级语言:当你用Python语言编写程序的时候,你无需考虑诸如如何管理你的程序使用的内存一类的底层细节;
4.可移植性:由于它的开源本质,Python已经被移植在许多平台上(经过改动使它能够工 作在不同平台上)。如果你小心地避免使用依赖于系统的特性,那么你的所有Python程序无需修改就几乎可以在市场上所有的系统平台上运行。
5.可扩展性(胶水语言):如果你需要你的一段关键代码运行得更快或者希望某些算法不公开,你可以把你的部分程序用C或C++编写,然后在你的Python程序中使用它们。
6.可嵌入性————你可以把Python嵌入你的C/C++程序,从而向你的程序用户提供脚本功能
缺点:
(1)速度慢:Python 的运行速度相比C语言确实慢很多,跟JAVA相比也要慢一些,因此这也是很多所谓的大牛不屑于使用Python的主要原因,但其实这里所指的运行速度慢在大多数情况下用户是无法直接感知到的,必须借助测试工具才能体现出来。
(2)代码不能加密,因为PYTHON是解释性语言,它的源码都是以名文形式存放的,不过我不认为这算是一个缺点,如果你的项目要求源代码必须是加密的,那你一开始就不应该用Python来去实现。
(3)线程不能利用多CPU问题,这是Python被人诟病最多的一个缺点,GIL即全局解释器锁(Global Interpreter Lock),是计算机程序设计语言解释器用于同步线程的工具,使得任何时刻仅有一个线程在执行,Python的线程是操作系统的原生线程。
5.字典按键或值排序
- 按键排序
dict1 = {'a': 3, 'b': 8, 'c': 5}
print(sorted(dict1.items(), key=lambda x: x[0]))
- 按值排序
dict1 = {'a': 3, 'b': 8, 'c': 5}
print(sorted(dict1.items(), key=lambda x: x[1]))
6.python的垃圾回收机制
引用计数、标记清除、分代回收
https://testerhome.com/topics/16556
https://www.cnblogs.com/aaronthon/p/9356685.html
7.赋值、深拷贝、浅拷贝
(1)赋值(别名)
在python中,对象赋值实际上是对象的引用。
当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用
(2)浅拷贝(藕断丝连)
copy浅拷贝,拷贝的顶层对象的引用,所以原始数据改变,子对象会改变
浅拷贝会创建新对象,其内容非原对象本身的引用,而是原对象内第一层对象的引用。
浅拷贝有三种形式:切片操作、工厂函数、copy模块中的copy函数。
(3)深拷贝(各行其道)
深拷贝,包含对象里面的子对象的递归拷贝。所以原始对象的改变不会造成深拷贝里任何子元素的改变。
深拷贝只有一种形式,copy模块中的deepcopy()函数。
深拷贝和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。因此,它的时间和空间开销要高。
注意:
- 对于非容器类型,如数字、字符,以及其他的“原子”类型,没有拷贝一说,产生的都是原对象的引用。
- 如果元组变量值包含可变类型,浅拷贝不创建新的对象,等同于引用。如果元组全是不可变类型,那么深浅拷贝都等同于引用。
8.正排索引和倒排索引
正排索引是从文档到关键字的映射(已知文档求关键字)
倒排索引是从关键字到文档的映射(已知关键字求文档)