V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
DaChuiZi
V2EX  ›  Python

Python 多层 for 循环性能如何提高

  •  
  •   DaChuiZi · 2022-09-29 11:00:48 +08:00 · 4522 次点击
    这是一个创建于 788 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在实际业务中不得不遍历多个嵌套 for 循环, 如何提高嵌套 for 循环的性能 耗时太长了~

    案例: 比如一把武器 for 一个武器 in 武器库: for 弹药 in 弹夹: if 弹药是否属于该武器: for 弹药属性 in 弹药: # 判断弹药是否支持攻击某种物体

    20 条回复    2022-09-30 14:40:08 +08:00
    Building
        1
    Building  
       2022-09-29 11:02:16 +08:00   ❤️ 1
    提前用字典存好
    eason1874
        2
    eason1874  
       2022-09-29 11:22:26 +08:00
    提前存好 +1

    最朴素的方法往往是最有效的
    dcty
        3
    dcty  
       2022-09-29 11:24:18 +08:00 via iPhone
    空间换时间
    SimonOne
        4
    SimonOne  
       2022-09-29 11:27:11 +08:00
    请问 while 循环的间隔是 0.2s-0.3s 左右,有方法可以减少吗?
    lookStupiToForce
        5
    lookStupiToForce  
       2022-09-29 11:34:17 +08:00
    把多层循环的内容根据逻辑改写难易丢 numpy 、丢 pandas 、丢数据库,最不济丢其他性能高的语言去处理呗

    像你题目中说的,感觉用一个 df.apply 就能解决,前提是 merge 上必要的信息列
    wxf666
        6
    wxf666  
       2022-09-29 11:34:42 +08:00
    同意 #1

    1. 种类不多,你可以存成 `set[tuple[弹药, 该弹药能攻击的物体]]`:

    ```python
    弹药能攻击的物体 = {
     (弹药 1, 物体 1),
     (弹药 1, 物体 2),
     (弹药 2, 物体 1),
     (弹药 2, 物体 3),
    }
    ```

    判断:`if (弹药 1, 物体 1) in 弹药能攻击的物体:`


    2. 种类巨多,可能存成 `dict[弹药, set[该弹药能攻击的物体]]` 能省点内存?但比上面的慢

    ```python
    弹药能攻击的物体 = {
     弹药 1: {物体 1, 物体 2},
     弹药 2: {物体 1, 物体 3},
    }
    ```

    判断:`if 物体 1 in 弹药能攻击的物体[弹药 1]:`
    qW7bo2FbzbC0
        7
    qW7bo2FbzbC0  
       2022-09-29 11:40:32 +08:00
    用二维数据结构组织既有信息

    也就是楼上说的用 map 或者 dict 来做
    wcsjtu
        8
    wcsjtu  
       2022-09-29 11:47:10 +08:00
    思路一:修改逻辑, 不要用 for 循环
    思路二:实在要用 for ,改成 C/C++循环, 可以使用 mypyc 编译该部分代码, 也可以用 cython 编译。mypyc 有语法要求, 性能稍微好一点。cython 可以直接编,性能比较差,但是还是远比 Python for 循环好

    我们团队搞了一个专门为 Python 业务逻辑加速的编译器,性能吊打 cython/mypyc/pypy , 可惜不能开源.......
    liuxingdeyu
        9
    liuxingdeyu  
       2022-09-29 11:51:54 +08:00
    map reduce ?
    xgdgsc
        10
    xgdgsc  
       2022-09-29 13:29:19 +08:00 via Android
    xsourse
        11
    xsourse  
       2022-09-29 13:47:57 +08:00
    numba
    princelai
        12
    princelai  
       2022-09-29 14:39:22 +08:00
    @xsourse #11 numba 不支持 list 结构,他这个 for in 明显是从序列中遍历呢,这个方法不行
    ericgui
        13
    ericgui  
       2022-09-29 14:45:07 +08:00
    用空间换时间,这是最简单的一个算法技巧
    DaChuiZi
        14
    DaChuiZi  
    OP
       2022-09-29 14:45:38 +08:00
    @wxf666 有思路了!感谢大佬!
    leonhao
        15
    leonhao  
       2022-09-29 15:16:10 +08:00
    多刷 leetcode
    LeegoYih
        16
    LeegoYih  
       2022-09-29 15:22:31 +08:00
    手动展开
    karloku
        17
    karloku  
       2022-09-29 18:33:22 +08:00
    长列表遍历本来就慢, python 的循环更是慢中慢...
    提前分类, 字典存好比较好
    scruel
        18
    scruel  
       2022-09-29 23:37:50 +08:00
    当然是直接换 python 14
    [python14!]( https://miro.medium.com/max/1100/1*ieMH6ipGpq72fWnMiKweHA.png)
    xuanbg
        19
    xuanbg  
       2022-09-30 08:36:51 +08:00
    全组合放数据库,直接查结果就行。
    wcsjtu
        20
    wcsjtu  
       2022-09-30 14:40:08 +08:00
    @xsourse 这种情况,numba 没用的,绝对是负优化。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2780 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 00:20 · PVG 08:20 · LAX 16:20 · JFK 19:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.