如何提高python 中for循环的效率

对于某个城市的出租车数据,一天就有33210000条记录,如何将每辆车的数据单独拎出来放到一个专属的文件中呢?

思路很简单:

就是循环33210000条记录,将每辆车的数据搬运到它该去的文件中。

但是对于3000多万条数据,一个一个循环太消耗时间,我花了2个小时才搬运了60万数据,算算3000万我需要花费100个小时,也就需要4-5天。并且还需要保证这五天全天开机,不能出现卡机的事故。

因此,需要使用并行进行for循环的技巧:

由于3000万数据放到csv中导致csv打不开,因此我就把一个csv通过split软件将其切分成每份60万,共53个csv。

我原来的思路是读取文件夹,获取由每一个60万的csv文件组成的列表,再分别对每一个60万的csv进行处理。实质上还是循环33210000次,并行for循环就是同时处理几个60万的csv文件,就能成倍的减少时间消耗。

并行进行for循环是受下面的方法启发:

我之前的做法类似这样:

  words = ['apple', 'bananan', 'cake', 'dumpling']
  for word in words:
    print word

并行for循环类似这样:

from multiprocessing.dummy import Pool as ThreadPool
items = list()
pool = ThreadPool()
pool.map(process, items)
pool.close()
pool.join()

其中,process是进行处理的函数

实例代码如下:

# -*- coding: utf-8 -*-
import time
from multiprocessing.dummy import Pool as ThreadPool
def process(item):
  print('正在并行for循环')
  print(item)
  time.sleep(5)
items = ['apple', 'bananan', 'cake', 'dumpling']
pool = ThreadPool()
pool.map(process, items)
pool.close()
pool.join()

补充知识:Python3用多线程替代for循环提升程序运行速度

优化前后新老代码如下:

from git_tools.git_tool import get_collect_projects, QQNews_Git
from threading import Thread, Lock
import datetime

base_url = "http://git.xx.com"
project_members_commits_lang_info = {}
lock = Lock()
threads = []

'''
Author:zenkilan
'''

def count_time(func):
  def took_up_time(*args, **kwargs):
    start_time = datetime.datetime.now()
    ret = func(*args, **kwargs)
    end_time = datetime.datetime.now()
    took_up_time = (end_time - start_time).total_seconds()
    print(f"{func.__name__} execution took up time:{took_up_time}")
    return ret

  return took_up_time

def get_project_member_lang_code_lines(git, member, begin_date, end_date):
  global project_members_commits_lang_info
  global lock
  member_name = member["username"]
  r = git.get_user_info(member_name)
  if not r["id"]:
    return
  user_commits_lang_info = git.get_commits_user_lang_diff_between(r["id"], begin_date, end_date)
  if len(user_commits_lang_info) == 0:
    return
  lock.acquire()
  project_members_commits_lang_info.setdefault(git.project, dict())
  project_members_commits_lang_info[git.project][member_name] = user_commits_lang_info
  lock.release()

def get_project_lang_code_lines(project, begin_date, end_date):
  global threads
  git = QQNews_Git(project[1], base_url, project[0])
  project_members = git.get_project_members()
  if len(project_members) == 0:
    return
  for member in project_members:
    thread = Thread(target=get_project_member_lang_code_lines, args=(git, member, begin_date, end_date))
    threads.append(thread)
    thread.start()

@count_time
def get_projects_lang_code_lines(begin_date, end_date):
  """
  获取项目代码行语言相关统计——新方法(提升效率)
  应用多线程替代for循环
  并发访问共享外部资源
  :return:
  """
  global project_members_commits_lang_info
  global threads
  for project in get_collect_projects():
    thread = Thread(target=get_project_lang_code_lines, args=(project, begin_date, end_date))
    threads.append(thread)
    thread.start()

@count_time
def get_projects_lang_code_lines_old(begin_date, end_date):
  """
  获取项目代码行语言相关统计——老方法(耗时严重)
  使用最基本的思路进行编程
  双层for循环嵌套并且每层都包含耗时操作
  :return:
  """
  project_members_commits_lang_info = {}
  for project in get_collect_projects():
    git = QQNews_Git(project[1], base_url, project[0])
    project_members = git.get_project_members()
    user_commits_lang_info_dict = {}
    if len(project_members) == 0:
      continue
    for member in project_members:
      member_name = member["username"]
      r = git.get_user_info(member_name, debug=False)
      if not r["id"]:
        continue
      try:
        user_commits_lang_info = git.get_commits_user_lang_diff_between(r["id"], begin_date, end_date)
        if len(user_commits_lang_info) == 0:
          continue
        user_commits_lang_info_dict[member_name] = user_commits_lang_info
        project_members_commits_lang_info[git.project] = user_commits_lang_info_dict
      except:
        pass
  return project_members_commits_lang_info

def test_results_equal(resultA, resultB):
  """
  测试方法
  :param resultA:
  :param resultB:
  :return:
  """
  print(resultA)
  print(resultB)
  assert len(str(resultA)) == len(str(resultB))

if __name__ == '__main__':
  from git_tools.config import begin_date, end_date

  get_projects_lang_code_lines(begin_date, end_date)
  for t in threads:
    t.join()
  old_result = get_projects_lang_code_lines_old(begin_date, end_date)
  test_results_equal(old_result, project_members_commits_lang_info)

老方法里外层for循环和内层for循环里均存在耗时操作:

1)git.get_project_members()

2)git.get_user_info(member_name, debug=False)

分两步来优化,先里后外或先外后里都行。用多线程替换for循环,并发共享外部资源,加锁避免写冲突。

测试结果通过,函数运行时间装饰器显示(单位秒):

get_projects_lang_code_lines execution took up time:1.85294

get_projects_lang_code_lines_old execution took up time:108.604177

速度提升了约58倍

以上这篇如何提高python 中for循环的效率就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • python用for循环求和的方法总结

    Python中可以使用for循环实现累加求和 for循环语法: for 变量 in range(x): 循环需要执行的代码 如下实现1到n求和: def main(): sum = 0 # 定义变量做累加器 n = int(input('n=')) #从键盘上输入累加的范围 for x in range(n): sum += (x + 1) print(sum) if __name__ == '__main__': main() 用for循环实现1~n求和的方法 def main():   su

  • 详解Python中for循环的使用方法

    for循环在Python中有遍历所有序列的项目,如列表或一个字符串. 语法: for循环语法如下: for iterating_var in sequence: statements(s) 如果一个序列包含一个表达式列表,计算第一个.然后,在序列中的第一项被分配给迭代变量iterating_var.接着,语句块被执行.列表中的每个项目分配给iterating_var,并且statement块被执行,直到整个序列完成(到尾部). 流程图: 例子: #!/usr/bin/python for let

  • Python for循环中的陷阱详解

    前言 Python 中的 for 循环和其他语言中的 for 循环工作方式是不一样的,今天就带你深入了解 Python 的 for 循环,看看它是如何工作的,以及它为什么按照这种方式工作. 循环中的陷阱 我们先来看一下 Python 循环中的「陷阱」,在我们了解了循环的工作方式后,再来看下这些陷阱到底是怎么出现的. 陷阱 1:循环两次 现在我们先假设有一个数字组成的列表,和一个用于返回这些数字的平方的生成器: >>> nums = [1, 2, 3, 4] >>> sq

  • 基于Numba提高python运行效率过程解析

    Numba是Python的即时编译器,在使用NumPy数组和函数以及循环的代码上效果最佳.使用Numba的最常见方法是通过其装饰器集合,这些装饰器可应用于您的函数以指示Numba对其进行编译.调用Numba装饰函数时,它会被"即时"编译为机器代码以执行,并且您的全部或部分代码随后可以本机机器速度运行! 安装numba(我在这里加了--default-timeout=10000,防止安装时出现timeout的错误) pip --default-timeout=10000 install

  • 如何提高python 中for循环的效率

    对于某个城市的出租车数据,一天就有33210000条记录,如何将每辆车的数据单独拎出来放到一个专属的文件中呢? 思路很简单: 就是循环33210000条记录,将每辆车的数据搬运到它该去的文件中. 但是对于3000多万条数据,一个一个循环太消耗时间,我花了2个小时才搬运了60万数据,算算3000万我需要花费100个小时,也就需要4-5天.并且还需要保证这五天全天开机,不能出现卡机的事故. 因此,需要使用并行进行for循环的技巧: 由于3000万数据放到csv中导致csv打不开,因此我就把一个csv

  • 聊聊python中的循环遍历

    python之循环遍历 关于循环遍历大家都知道,不外乎for和while,今天我在这写点不一样的循环和遍历.在实践中有时会遇到删除列表中的元素,那么循环遍历列表删除指定元素该怎么做呢? 还是直接上代码看案例吧: import time # 删除下面列表中所有张姓元素,输出的结果应该是['李老大','李老二'] lst = ['张老大', '张老二', '李老大', '张老三', '李老二']*10000 # 直接for循环遍历列表,remove需要删除的元素 def del1(lst): for

  • 源码解析python中randint函数的效率缺陷

    目录 一.前言 二.对randint()运行效率的测试 三.从源码分析randint()的缺陷 random.random() random.randint() 四.更快的生成随机整数的方法 random.random() 直接使用 getrandbits() 使用 Numpy.random 一.前言 前几天,在写一个与差分隐私相关的简单程序时,我发现了一些奇怪的东西:相对于其他的随机数生成函数,Python的random.randint()函数感觉很慢. 由于 randint() 是 Pyth

  • python中while循环语句用法简单实例

    本文实例讲述了python中while循环语句用法.分享给大家供大家参考.具体如下: number = 1 while number < 20: print(number) number += 1 运行结果如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 希望本文所述对大家的Python程序设计有所帮助.

  • python中list循环语句用法实例

    本文实例讲述了python中list循环语句用法.分享给大家供大家参考.具体用法分析如下: Python 的强大特性之一就是其对 list 的解析,它提供一种紧凑的方法,可以通过对 list 中的每个元素应用一个函数,从而将一个 list 映射为另一个 list. 实例 复制代码 代码如下: a = ['cat', 'window', 'defenestrate'] for x in a:      print x, len(x) for x in [1, 2, 3]: print x,    

  • Python中for循环控制语句用法实例

    本文实例讲述了Python中for循环控制语句用法.分享给大家供大家参考.具体分析如下: 第一个:求 50 - 100 之间的质数 import math for i in range(50, 100 + 1): for j in range(2, int(math.sqrt(i)) + 1): if i % j == 0: break else: print i 输出如下: 53 59 61 67 71 73 79 83 89 97 第二个:把else的位置与if处于同一缩进. import

  • python中for循环把字符串或者字典添加到列表的方法

    python中如何for循环把字符串添加到列表? 实例: 1.单个字符串用for循环添加到列表中: # 把L1中的字符串添加到列表alist里面 L1 = 'MJlifeBlog' alist = [] # 可以用forin来迭代L1并保存值到x变量里头即可. # 接着在for循环里边用append方法即可把解析到的单个字符添加到列表了. for x in L1: alist.append(x) print(alist) 2.多个字符串用for循环添加到列表中: # 如果需要把多个字符串添加到列

  • python中for循环输出列表索引与对应的值方法

    如下所示: list = ['a','b','c'] 想用for循环输出list的元素以及对应的索引. 代码及结果如下: 以上这篇python中for循环输出列表索引与对应的值方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • python中for循环变量作用域及用法详解

    在讲这个话题前,首先我们来看一道题: 代码1: def foo(): return [lambda x: x**i for i in range(1,5,2)] print([f(3) for f in foo()]) 伙伴们,你们认为这里产生的结果是什么呢?我们再来看下这题的变体: 代码:2 def foo(): functions=[] for i in range(1,5,2): def inside_fun(x): return x ** i functions.append(insid

  • Python中无限循环需要什么条件

    无限循环 如果条件判断语句永远为 true,循环将会无限的执行下去. 如下实例 #!/usr/bin/python # -*- coding: UTF-8 -*- var = 1 while var == 1 : # 该条件永远为true,循环将无限执行下去 num = raw_input("Enter a number :") print "You entered: ", num print "Good bye!" 以上实例输出结果: Ente

随机推荐