RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1565980
Accepted
Глеб
Глеб
Asked:2024-02-12 18:53:58 +0000 UTC2024-02-12 18:53:58 +0000 UTC 2024-02-12 18:53:58 +0000 UTC

解析Python中的循环结构

  • 772

假设我们有某种列表:

>>> l = [1, 2, 3, [4, [5], [6, 7]]]

我们需要找出它的各项之和。一切都清楚了,正常的递归:

>>> def list_sum(l):
        r = 0
        for i in l:
            if type(i) == int:
                r += i
            elif type(i) == list:
                r += list_sum(i)
        return r

>>> list_sum(l)
28

现在我们将对列表做一些事情。

>>> l.append(l)
>>> l
[1, 2, 3, [4, [5], [6, 7]], [...]]

这称为“循环”列表。让我们再次尝试计算项之和。而且当然...

>> list_sum(l)
    Traceback (most recent call last):
      File "<pyshell#22>", line 1, in <module>
        list_sum(l)
      File "<pyshell#17>", line 7, in list_sum
        r += list_sum(i)
      File "<pyshell#17>", line 7, in list_sum
        r += list_sum(i)
      File "<pyshell#17>", line 7, in list_sum
        r += list_sum(i)
      [Previous line repeated 1022 more times]
      File "<pyshell#17>", line 4, in list_sum
        if type(i) == int:
    RecursionError: maximum recursion depth exceeded in comparison

那么,该如何处理呢?

>>> def new_sum(l):
        r = 0
        for i in l:
            if type(i) == int:
                r += i
            elif type(i) == list:
                if i is l:
                    pass
                else:
                    r += new_sum(i)
        return r

>>> new_sum(l)
28

让我们更加混淆这个列表:

>>> l[3].append(l)
>>> l
[1, 2, 3, [4, [5], [6, 7], [...]], [...]]

...并且不再有效:

>>> new_sum(l)
    Traceback (most recent call last):
      File "<pyshell#40>", line 1, in <module>
        new_sum(l)
      File "<pyshell#36>", line 10, in new_sum
        r += new_sum(i)
      File "<pyshell#36>", line 10, in new_sum
        r += new_sum(i)
      File "<pyshell#36>", line 10, in new_sum
        r += new_sum(i)
      [Previous line repeated 1022 more times]
      File "<pyshell#36>", line 4, in new_sum
        if type(i) == int:
    RecursionError: maximum recursion depth exceeded in comparison
    

问题:是否可以实时解析这样的结构?我当然可以编写一个详尽的搜索函数,不会让递归进入循环,但算法的复杂度显然会增加几个数量级。是否有算法可以加快“通过”此类列表的速度?

PS 不,这是一个纯粹的理论任务。如果我尝试不在 Python 中而是在 Explorer 中实现这一点,那么 Windows 会很快告诉我它对我的所有想法。所以这个任务没有真正的类似物。我只是无事可做)

python
  • 1 1 个回答
  • 67 Views

1 个回答

  • Voted
  1. Best Answer
    Stanislav Volodarskiy
    2024-02-12T23:59:24Z2024-02-12T23:59:24Z

    NB过滤和过滤的思想正是id借用了问题的评论。

    该函数traverse遍历嵌套列表。循环链接通过访问过的集合进行过滤id- visited。与图的深度优先遍历没有太大区别:

    def traverse(v):
        visited = set()
    
        def rec(v):
            if isinstance(v, list):
                if id(v) not in visited:
                    visited.add(id(v))
                    for vv in v:
                        yield from rec(vv)
            else:
                yield v
    
        yield from rec(v)
    
    
    lst = [1, 2, 3, [4, [5], [6, 7]]]
    lst.append(lst)
    lst[3].append(lst)
    print(lst)
    print(*traverse(lst))
    print(sum(traverse(lst)))
    
    $ python traverse.py
    [1, 2, 3, [4, [5], [6, 7], [...]], [...]]
    1 2 3 4 5 6 7
    28
    

    PS一旦发生了递归,就需要添加不带递归的版本。遍历节点的顺序颠倒了,但含义是一样的:

    def traverse(v):
        visited = set()
    
        stack = [v]
        while stack:
            v = stack.pop()
            if isinstance(v, list):
                if id(v) not in visited:
                    visited.add(id(v))
                    # stack.extend(reversed(v))  # если нужно сохранить порядок
                    stack.extend(v)
            else:
                yield v
    
    
    lst = [1, 2, 3, [4, [5], [6, 7]]]
    lst.append(lst)
    lst[3].append(lst)
    print(lst)
    print(*traverse(lst))
    print(sum(traverse(lst)))
    
    $ python traverse.py
    [1, 2, 3, [4, [5], [6, 7], [...]], [...]]
    7 6 5 4 3 2 1
    28
    
    • 3

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5