调试列表理解的技巧?

发布于 2024-08-27 02:27:51 字数 47 浏览 6 评论 0原文

Python 列表推导式很好,但几乎不可能调试。你们有什么好的调试技巧/工具吗?

Python list comprehensions are nice, but near impossible to debug. You guys have any good tips / tools for debugging them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

待天淡蓝洁白时 2024-09-03 02:27:51

我使用一个只同时打印和返回值的函数:

from pprint import pprint

def debug(msg, item):
    print('\n' + msg + ':')
    pprint(item)
    return item

它对于调试列表/字典理解的任何部分非常方便:

new_lines = [
    debug('CUR UPDATED LINE', change(line))
    for line
    in debug('ALL LINES', get_lines_from_file(filename))
    if debug('CUR LINE EMPTY?', not_empty(line))
    ]

I use a function that just prints and returns a value at the same time:

from pprint import pprint

def debug(msg, item):
    print('\n' + msg + ':')
    pprint(item)
    return item

It's very handy for debugging any part of a list/dict comprehension:

new_lines = [
    debug('CUR UPDATED LINE', change(line))
    for line
    in debug('ALL LINES', get_lines_from_file(filename))
    if debug('CUR LINE EMPTY?', not_empty(line))
    ]
弄潮 2024-09-03 02:27:51

这取决于列表理解。您可以将部分代码移至另一个函数。这应该是一个更容易调试的干净解决方案。

示例:

[1.0 / i for i in [0, 2, 5, 10]]

可以分为

[f(i) for i in [0, 2, 5, 10]] 

和 一个函数

def f(i):         
    return 1.0 / i  

当您进行调试时,您会发现它会崩溃,因为 f 的值 i = 时出现“被零除”错误0 。

It depends on the list comprehension. You can move a part of the code to another function. This should be a clean solution which is more easy to debug.

Example:

[1.0 / i for i in [0, 2, 5, 10]]

Can be divided into

[f(i) for i in [0, 2, 5, 10]] 

and a function

def f(i):         
    return 1.0 / i  

When you do the debugging you will find out it will crash because of a “division-by-zero” error at f for the value of i = 0.

殊姿 2024-09-03 02:27:51

如果它足够复杂以至于乍一看并不明显,请将其解压缩为多个步骤和/或 for 循环。它显然太复杂了,使其更明确是调试它的最简单方法。额外的好处:您现在可以使用调试器逐步执行或添加打印语句!

If it's complicated enough that it's not obvious at first glance, unpack it into multiple steps and/or for loops. It's clearly too complicated, and making it more explicit is the easiest way to go about debugging it. Added bonus: you can now step through with the debugger or add print statements!

不离久伴 2024-09-03 02:27:51

在 Haskell 中我使用类似的东西:

def trcPV(prompt, value):
    print ("%s%s" % (prompt, str(value)))
    return value

xs = trcPV("xs=", [x for x in range(0,100) if trcPV("check=",(trcPV("x=",x) % 15) in [0,3,5])])

In Haskell I using something similar to:

def trcPV(prompt, value):
    print ("%s%s" % (prompt, str(value)))
    return value

xs = trcPV("xs=", [x for x in range(0,100) if trcPV("check=",(trcPV("x=",x) % 15) in [0,3,5])])
思念绕指尖 2024-09-03 02:27:51

提示:对简单任务(1 或 2 级)使用列表理解。否则,将其明确化更有利于可读性。

tip: Use list comprehension for simple tasks (1 or 2 levels). Otherwise, making it explicit is better for readability.

极致的悲 2024-09-03 02:27:51

使用像 pdb 这样的调试器来遍历或将列表理解分解为完整的 for 循环。

Use a debugger like pdb to walk through or break the list comprehension into a full for loop.

我不吻晚风 2024-09-03 02:27:51

Haskell 列表推导式至少可以(这就是编译器所做的)根据映射、连接和过滤器进行重写。

因此,这个 Haskell 示例:

[ x*x | x<-[1..25], even x]

计算结果为:

map (\x-> x*x) (filter (even) [1..25])

我预计类似的恒等式将继续适用于 Python,因此类似的分解也应该在 Python 中产生等效的代码。等效代码应该更容易调试(并且运行效率也差不多)。

Haskell list comprehensions at least can be (and that is what compilers do) rewritten in terms of map, concat and filter.

So this Haskell example:

[ x*x | x<-[1..25], even x]

Works out as:

map (\x-> x*x) (filter (even) [1..25])

I expect similar identities would continue to hold for Python, so similar decomposition should yield equivalent code in Python as well. The equivalent code should prove easier to debug (and run about as efficiently).

冷…雨湿花 2024-09-03 02:27:51

https://stackoverflow.com/a/39350403/5339264 中的 Elmex80s 非常好的响应基础上,使用调试功能可以还可以帮助解决 TypeError: unsupported operand type(s) for +: 'method' and 'str' 或列表理解中的类似错误。

经典内容

def debug(i):
    print(f"i: {i}, {str(type(i))}")

列表理解中的

[debug(item) for item in list]

对于弄清楚列表中的哪个项目导致错误非常有用。

Building on Elmex80s very nice response in https://stackoverflow.com/a/39350403/5339264, using a debug function can also help with TypeError: unsupported operand type(s) for +: 'method' and 'str' or similar errors in a list comprehension.

A classic

def debug(i):
    print(f"i: {i}, {str(type(i))}")

in a list comprehension like

[debug(item) for item in list]

can be very useful to unravel what item in the list is causing the error.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文