ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Python生成器:处理百万数据不爆内存,90%程序员都用错了

Python生成器:处理百万数据不爆内存,90%程序员都用错了 一、同样写为啥别人处理百万数据不卡进行开发工作的人员, 差不多所有人都会碰到同一类问题: 编写完成且质量合格的代码, 在应对少量数据时运行十分顺畅, 然而一旦将数据量替换成几十万条甚至上百万条, 程序就会直接僵死, 甚至还会弹出提示“内存不足”的错误信息。有些人花费高额费用去升级服务器, 有些人熬夜费力地优化代码, 在一番折腾之后却发觉, 问题的根源根本不在于硬件以及代码逻辑, 而是在于没有运用到里面堪称“隐藏王牌”的生成器。它无需多出一行复杂代码, 无需额外添加插件, 便可轻松处理百万条甚至于千万条数据, 且不占用内存, 不卡顿进程, 堪称大数据处理方面的“效率神器”。然而令人遗憾的是, 多数程序员要么根本就不知道它, 要么仅仅只会运用其皮毛, 白白地浪费了这个核心功能。相比之下更令人心里难受的是, 同样是针对大数据展开处理操作, 运用列表方式的程序员一直熬到了凌晨时分, 仍旧还在进行程序调试工作, 而采用生成器方式的人员却早早地就下班归家了, 这般差距向来都并非是技术水平的高与低, 而是在于是否找到了恰当适用的得力工具。生成器的核心优势要先跟大家讲明白, 它是完全免费的, 它是以开源形式存在的, 它属于内置功能, 不需要另外去安装任何库, 在关联那上面相关开源项目星标累计超过10万, 它是被社区公认的“大数据处理救星”, 不管是新手, 还是资深程序员, 学会即能直接运用的 。二、核心拆解3分钟学会生成器小白也能上手若要弄清楚生成器, 首先必须明晰它所解决的核心痛点, 也就是列表的“致命缺陷”, 第二步再一步步透彻掌握生成器的用法, 整个过程都会附带代码, 只要复制便能够运行。1. 先避坑列表处理大数据的“噩梦”存在着不少程序员, 惯于运用列表来存储数据, 举例而言, 倘若要构建一个拥有100万条数据的列表, 代码将会如此去编写:# 列表推导式创建100万条数据 numbers [i for i in range(1000000)]看似简易的一行代码, 背后隐匿着大问题, 它会径直装载这 100 万条数据致使其通通进入内存, 这等效于将所有事物一下子都塞入仓库之中, 如此一来便会让内存占用瞬间急剧攀升。倘若数据量上涨至1亿条, 又或者涨至10亿条, 再或者替换成超大日志文件, 亦或是换成流式数据, 那么内存根本承受不住, 程序会直接崩溃, 这同样是诸多大数据程序“卡壳”的根源所在。2. 生成器登场只“按需生产”不浪费一点内存可以这样表述: 生成器的核心逻辑是这样的, 它不会去提前存储涉及的所有那个数据, 而是采用“按需进而生成”的措施, 每用出一条, 就产生一条, 一旦用完便予以释放, 在整个过程当中都不会占用多余的内存, 就是如此。仍旧是创建100万条数据, 运用生成器仅仅只需改动一个符号, 也就是把列表的换成括号形式的():# 生成器表达式创建100万条数据按需生成 numbers (i for i in range(1000000))这一行代码, 不会马上就生成100万条数据, 只有在你去对它进行迭代的时候比如说使用for循环, 它才会一条一条地去生成, 生成一条之后, 使用一条, 接着释放一条, 就算是面对10亿条数据, 也能够轻轻松松地应对。3. 核心用法yield关键字生成器的“灵魂”生成器, 除了可以借助生成器表达式来创建, 还能够运用函数并加yield关键字达成, 而这, 同样是在实际开发期间极为常用的一种方式, 接下来, 下面请先观赏下代码示例:# 定义一个生成器函数计数到n def count_up_to(n): i 1 while i n: yield i # 关键yield暂停函数返回当前值 i 1 # 使用生成器 for number in count_up_to(5): print(number)运行结果如下1 2 3 4 5在此处的yield关键字, 那可就是生成器所具有的如同核心精髓般的存在, 它跟别的情况乃是有着本质方面的差异, 仅仅通过一张表格就能够清晰地看明白:关键字作用执行后直接结束函数释放所有状态无法再继续执行yield将函数停止执行, 把当下全部状态予以保存, 再次调用之际能从停止的位置接着执行。大体来讲, yield宛如一个“ ”检查点, 它可使函数在既能够返回取值的同时, 还不至于遭遇“一口气便全部运行完毕”的情况, 进而达成“产生→停顿下来→ ”的运转循环, 而这同样也是生成器能够节省内存的关键缘故所在。4. 进阶用法无限生成器生成器管道生成器的强势所在, 在于可以缔造无限序列, 并且通过链式组合形成“数据管道”, 用以处置繁杂的大数据流程。 句号。先看无限生成器永远生成数据不会结束# 定义一个无限计数器生成器 def infinite_counter(): i 1 while True: # 无限循环 yield i i 1 # 使用无限生成器按需获取不会卡死 counter infinite_counter() print(next(counter)) # 输出1 print(next(counter)) # 输出2 print(next(counter)) # 输出3再看生成器管道多生成器链式调用 lazy 处理数据# 1. 生成100万条基础数据 numbers (i for i in range(1000000)) # 2. 对每条数据求平方 squares (i*i for i in numbers) # 3. 筛选出偶数平方 even_squares (i for i in squares if i % 2 0) # 迭代执行直到需要时才处理数据 for num in even_squares: print(num)在整个流程里面, 不存在任何一个步骤会将所有的数据都加载至内存, 每一个步骤仅仅处理当下的数据, 就算是有着1000万条数据, 也能够实现高效运行。三、辩证分析生成器再好也不是万能的不得不承认, 生成器针对大数据、流式数据进行处理之际, 其优势较列表有过之而无不及, 堪称程序员的“必备工具”。然而, 它并非毫无瑕疵, 一旦盲目运用, 反倒会事与愿违, 务必留意这3个局限。其一, 生成器仅能进行一次迭代。一旦你把生成器里的全部数据都迭代完毕, 它就会处于“耗尽”状态, 没办法再次进行迭代, 例如gen (i for i in range(3)) # 第一次迭代 for i in gen: print(i) # 输出1、2、3 # 第二次迭代无输出 for i in gen: print(i)这一点可完全区别于列表, 列表能够进行反复迭代, 生出的器一旦耗用尽了, 便需求重新实施创建, 这同样是好多新手极易遭遇到的困处。第二, 不是那种能够随机进行访问的。列表, 能够借助索引直接去获取处于指定位置的数据, 比如说, 然而生成器却做不到这项操作, 它, 仅仅只能从起始点开始, 一步一步地去进行迭代, 没办法跳过某一条数据, 直接对指定位置展开访问。其三, 不合乎小数据情形。要是数据数量极少, 像是几百条、几千条这般, 运用生成器反倒会增添些许性能方面的花费, 在这种时候采用列表更为简便、更具效率。所以, 从辩证的角度来看, 生成器的核心价值在于解决大数据内存问题, 在小数据场景中没必要强行采用, 它属于高效工具, 并非万能工具, 只有选对场景才能将其最大价值发挥出来。这也为程序员敲响了警钟, 技术不存在优劣之分, 仅存在适配与否的状况, 若盲目跟风去运用“高级功能”, 反倒会弄巧成拙, 起到相反效果。四、现实意义学会生成器能解决哪些实际问题诸多程序员觉着“生成器没作用”, 实则是尚未碰到相应场景。于实际开发里, 只要牵涉“大量数据处置”, 生成器就能够发挥大作用, 这4个高频次场景, 差不多每个程序员都会碰到。1. 读取那种容量极大的文件, 像是一些有着几GB甚至几十GB大小的日志文件以及CSV文件, 要是采用平常的办法, 将会把整个文件都加载到内存之中进而直接导致程序卡死而要是使用生成器逐行去读取, 就能轻轻松松地进行处理, 代码如下:def read_large_file(file_path): with open(file_path, r, encodingutf-8) as f: for line in f: # 逐行读取按需生成 yield line # 使用生成器读取超大文件 for line in read_large_file(large_file.log): # 处理每一行数据 print(line.strip())2. 要进行流式数据处理, 比如说要接收实时的数据流, 还要接收从API接口返回的海量数据, 生成器能够实时对每条数据予以处理, 这样不用等待所有数据加载完成, 可提升程序的响应速度。3. 数据库进行批量处理, 在数据库表存在百万级记录的时候, 以及存在千万级记录的情况下, 采用生成器来进行批量读取, 并且进行批量处理, 这样能够避免因为一次性加载所有记录从而导致的内存溢出情况, 与此同时还能减轻数据库所承受的压力。4. 无穷无尽的序列情形, 像是搞出一个没有尽头的计数器, 还有定时去产生数据的任务, 借助生成器便能够轻易达成, 无需另外去编排繁杂的循环逻辑。尤为关键的是, 生成器已然融入的核心生态之中, 就像range()函数、文件迭代诸如此类常用工具, 其背后均运用到了生成器的逻辑。掌握生成器, 不仅能够解决当下所面临的大数据问题, 而且还能够更为深入地去理解其底层的运行机制, 进而提升自身的技术功底。对于身为程序员而言, 要是掌握了生成器, 那就等同于多了一项“职场竞争力”呢, 就同一项工作来讲, 你能够更为快速地、更加高效地去完成它, 一旦遭遇到和大数据牵连着的需求之时, 你能够从容应对, 并非是毫无办法、手足无措。五、互动话题你踩过生成器的坑吗于此处看到, 想必你已然弄明白生成器的运用方法、具备的优势以及存在的局限, 并且也清楚它在实际开展项目过程当中所拥有的价值了。实则有不少程序员, 要不晓得生成器的存有, 要不于使用之际踩掠过坑, 像是不经意间使生成器耗空了, 又或是在小数据情形下强行运用生成器, 反倒致使效率降低了。到评论区去展开交流吧: 在你平常运用处理大数据期间, 是否遭遇过内存不足这种状况? 你是否使用过生成器? 曾不慎踏入过怎样的不良境地?此外, 要是你拥有生成器的实用窍门, 或者碰到过相关的棘手问题, 同样能够在评论区予以分享, 而后咱们一同展开交流学习, 进而提高实战能力。
返回列表