题目:有一个jsonline格式的文件file.txt大小约为10K

def get_lines():
with open('file.txt','rb') as f:
return f.readlines() if __name__ == '__main__':
for e in get_lines():
process(e) # 处理每一行数据

现在要处理一个大小为10G的文件,但是内存只有4G,如果在只修改get_lines 函数而其他代码保持不变的情况下,应该如何实现?需要考虑的问题都有那些?

def get_lines():
with open('file.txt','rb') as f:
for i in f:
yield i

方法:

from mmap import mmap

def get_lines(fp):
with open(fp,"r+") as f:
m = mmap(f.fileno(), 0)
tmp = 0
for i, char in enumerate(m):
if char==b"\n":
yield m[tmp:i+1].decode()
tmp = i+1 if __name__=="__main__":
for i in get_lines("fp_some_huge_file"):
print(i)

要考虑的问题有:内存只有4G无法一次性读入10G文件,需要分批读入分批读入数据要记录每次读入数据的位置。分批每次读取数据的大小,太小会在读取操作花费过多时间。

mmap函数

mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。

下面说一下内存映射的步骤:
1、用open系统调用打开文件, 并返回描述符fd.
2、用mmap建立内存映射, 并返回映射首地址指针start.
3、对映射(文件)进行各种操作, 显示(printf), 修改(sprintf).
4、用munmap(void *start, size_t lenght)关闭内存映射.
5、用close系统调用关闭文件fd.

系统调用mmap()用于共享内存的两种方式:
(1)使用普通文件提供的内存映射:
适用于任何进程之间。此时,需要打开或创建一个文件,然后再调用mmap()

(2)使用特殊文件提供匿名内存映射:

适用于具有亲缘关系的进程之间。由于父子进程特殊的亲缘关系,在父进程中先调用mmap(),然后调用 fork()。那么在调用fork()之后,子进程继承父进程匿名映射后的地址空间,同样也继承mmap()返回的地址,这样,父子进程就可以通过映射区 域进行通信了。注意,这里不是一般的继承关系。一般来说,子进程单独维护从父进程继承下来的一些变量。而mmap()返回的地址,却由父子进程共同维护。 对于具有亲缘关系的进程实现共享内存最好的方式应该是采用匿名内存映射的方式。此时,不必指定具体的文件,只要设置相应的标志即可。

参考博文:

https://blog.csdn.net/bbzhaohui/article/details/81665370

https://blog.csdn.net/yangle4695/article/details/52139585

enumerate()函数

  • enumerate()是python的内置函数
  • enumerate在字典上是枚举、列举的意思
  • 对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值
  • enumerate多用于在for循环中得到计数
  • 例如对于一个seq,得到:

  • (0, seq[0]), (1, seq[1]), (2, seq[2])

    enumerate()返回的是一个enumerate对象

enumerate()使用

  • 如果对一个列表,既要遍历索引又要遍历元素时,首先可以这样写:
list1 = ["这", "是", "一个", "测试"]
for i in range (len(list1)):
print i ,list1[i]

输出:这是一个测试

  • 上述方法有些累赘,利用enumerate()会更加直接和优美:
list1 = ["这", "是", "一个", "测试"]
for index, item in enumerate(list1):
print index, item
>>>
0 这
1 是
2 一个
3 测试
  • enumerate还可以接收第二个参数,用于指定索引起始值,如:
list1 = ["这", "是", "一个", "测试"]
for index, item in enumerate(list1, 1):
print index, item
>>>
1 这
2 是
3 一个
4 测试

补充

如果要统计文件的行数,可以这样写:

count = len(open(filepath, 'r').readlines())

这种方法简单,但是可能比较慢,当文件比较大时甚至不能工作。

可以利用enumerate():

count = 0
for index, line in enumerate(open(filepath,'r')):
count += 1

参考内容:https://www.cnblogs.com/quietwalk/p/7997850.html

python面试的100题(1)的更多相关文章

  1. python面试的100题(2)

    def print_directory_contents(sPath): """ 这个函数接收文件夹的名称作为输入参数 返回该文件夹中文件的路径 以及其包含文件夹中文件的 ...

  2. python面试的100题(21)

    正则表达式 94.请写出一段代码用正则匹配出ip? ip地址的生成规则. IP地址,是由32位数字二进制转为四个十进制的字符串组成. 怎么转化?下面讲解: 二进制:111111111111111111 ...

  3. python面试的100题(20)

    76.递归函数停止的条件? 递归的终止条件一般定义在递归函数内部,在递归调用前要做一个条件判断,根据判断的结果选择是继续调用自身,还是return:返回终止递归.终止的条件:1.判断递归的次数是否达到 ...

  4. python面试的100题(14)

    32.请写出一个函数满足以下条件 该函数的输入是一个仅包含数字的list,输出一个新的list,其中每一个元素要满足以下条件: 1.该元素是偶数 2.该元素在原list中是在偶数的位置(index是偶 ...

  5. python面试的100题(8)

    企业面试题 15.python新式类和经典类的区别? (在Python 2及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会获得所有“新式类”的特性 ...

  6. python面试的100题(4)

    4.打乱一个排好序的list对象alist? import random alist = [1,2,3,4,5] random.shuffle(alist) print(alist) 结果为:[2, ...

  7. python面试的100题(19)

    61.如何在function里面设置一个全局变量 Python中有局部变量和全局变量,当局部变量名字和全局变量名字重复时,局部变量会覆盖掉全局变量. 如果要给全局变量在一个函数里赋值,必须使用glob ...

  8. python面试的100题(18)

    函数 52.python常见的列表推导式? 列表推导式书写形式: [表达式 for 变量 in 列表] 或者 [表达式 for 变量 in 列表 if 条件] 参考地址:https://www.cnb ...

  9. python面试的100题(17)

    内存管理与垃圾回收机制 48.哪些操作会导致Python内存溢出,怎么处理? 内存溢出:你申请了10个字节的内存,但写入了大于10个字节的数据会导致内存溢出 内存溢出原因:1.内存中加载的数据量过于庞 ...

  10. python面试的100题(16)

    Python高级 元类 42.Python中类方法.类实例方法.静态方法有何区别? 类方法: 是类对象的方法,在定义时需要在上方使用 @classmethod 进行装饰,形参为cls,表示类对象,类对 ...

随机推荐

  1. 书写makefile的注意点

    1.空格 定义一个变量时用“foo = 1”这种形式,1后面千万不可以有空格,否则,foo的值为“1 ”.等于号和1之间的空格有无,并没有关系. 2.ifeq ifeq的形式是“ifeq ($(foo ...

  2. 菜不成声 的 ac自动机 刷题记录

    HDU2222 Keywords Search 模板题.数组开小了结果会T... 代码 #include <bits/stdc++.h> #define nmax 10010 using ...

  3. Wannafly Camp 2020 Day 2J 邦邦的2-SAT模板

    #include <bits/stdc++.h> using namespace std; int main() { int n; cin>>n; cout<<n& ...

  4. C语言链表头插法逆向输出

    输入:1 2 3 4 5 -1 输出:5 4 3 2 1 此题考查头链表的创建之一 :头插法.所谓头插法是从一个空链表开始,重复读入数据,生成新结点,将读入的数据存放新结点的数据域中,然后讲新结点插入 ...

  5. mysql远程链接(可以在服务器上配置然后在本地连接远程服务器)

    ps:如果一下的连接不成功原因:一定要关闭windows防火墙或者linux的防火墙 1.在服务器端授权(黄色标记的地方第一个是用户名,第二个的意思是可以远程连接,第三个是密码) GRANT ALL  ...

  6. matlab中的数组与矩阵

    今天做图像处理时,看到一个矩阵的处理,简要谈谈下面几段代码: 首先是介绍矩阵(说明:在matlab中无是数组还是矩阵都是按列来存储的) 首先是一些特殊矩阵的建立 zeros(m,n)%建立全0矩阵 o ...

  7. moveTo 与 moveBy的区别 (转贴)

    MoveTo和MoveBy可以使精灵移动,区别在于MoveTo是移动到给定的坐标点:而MoveBy是从当前坐标点移动给定的坐标点这么多的距离.举个例子,假定精灵当前的坐标点是(x, y),分别给Mov ...

  8. 怎么把apk文件部署在云服务器上

    你服务器直接使用nginx,将请求映射到固定目录,把你的apk放到该目录.其他都不用干了.

  9. Oracle用户权限授权以及索引、同义词、分区

    本文为原创,如需转载,请标明出处 http://www.cnblogs.com/gudu1/p/7601765.html ---- 用户权限 1.创建表空间 (创建用户之前需要创建表空间和临时表空间, ...

  10. Jquery插件 之 zTree树加载

    原文链接:https://blog.csdn.net/jiaqu2177/article/details/80626730 zTree树加载 zTree 是一个依靠 jQuery 实现的多功能 “树插 ...