Python中的Prolog单例变量

时间:2012-12-19 22:09:20

标签: python unused-variables

我正在使用python中的一些脚本,我来到了这个:

line = "a b c d e f g"
a, b, c, d, e, f, g = line.split()

我很清楚这些是在实现过程中做出的决定,但不应该(或确实)python提供类似的东西:

_, _, var_needed, _, _, another_var_needed, _ = line.split()

以及Prolog确实提供,以排除着名的singleton variables

我不确定,但不会避免不必要的分配吗?或者创建对split调用结果的引用并不算作开销?

修改

对不起,我的观点是:在Prolog中,就我而言,在一个表达式中:

test(L, N) :-
    test(L, 0, N).
test([], N, N).
test([_|T], M, N) :-
    V is M + 1,
    test(T, V, N).

_表示的变量不可访问,因为我认为甚至没有创建列表[_|T]中存在的值的引用。

但是,在Python中,如果我使用_,我可以使用分配给_的最后一个值,而且,我确实会为每个变量_进行赋值。 - 这可能被视为开销。

我的问题是,是否应该(或者如果有)语法来避免这种不必要的归因。

3 个答案:

答案 0 :(得分:7)

_是一个完全有效的变量名称,是的,您可以在解包操作中多次使用变量,因此您编写的内容将起作用。 _将以该行中指定的最后一个值结束。一些Python程序员确实以这种方式使用它。

_被一些Python交互式shell用于特殊目的,这可能会使一些读者感到困惑,因此一些程序员因此而使用它。

没有办法避免使用str.split()进行分配:它总是分割整行,并且始终分配结果字符串。就是这样,在这种情况下,其中一些不会活得很长。但话说回来了,谁呢?

您可以使用re.finditer()来避免某些分配:

import re

fi = re.finditer(r"\S+", line)
next(fi)
next(fi)
var_needed = next(fi).group()
next(fi)
next(fi)
another_var_needed = next(fi).group()
# we don't care about the last match so we don't ask for it

next()返回一个Match对象,因此它将被分配(并立即丢弃,因为我们没有将其保存在任何地方)。所以你真的只保存最后的分配。如果你的字符串很长,那么你得到一个Match对象而不是一个字符串的事实可以节省一些内存甚至时间,我想;我认为匹配的字符串在您要求之前不会从源字符串中切除。您可以对其进行分析以确定。

您甚至可以将上述内容概括为一个只从字符串中返回所需标记的函数:

import re

def get_tokens(text, *toknums):
    toknums = set(toknums)
    maxtok = max(toknums)
    for i, m in enumerate(re.finditer(r"\S", text)):
        if i in toknums:
            yield m.group()
        elif i > maxtok:
            break

var1, var2 = get_tokens("a b c d e f g", 2, 5)

但它仍然不是很漂亮。

答案 1 :(得分:3)

事实上,_是Python中的有效标识符,人们经常使用它来接受一个不再需要的值,所以你的代码已经很棒了。

Python中没有与Prolog中的_完全对应的语法。在Python中使用_时,它是一个真正的变量,它实际上包含对值的引用。

也就是说,运行Python程序时分配和释放了许多对象。即使你可以像你所展示的那样控制一些地方,它也只是一个下降,并且不会影响你的程序的资源使用情况。

答案 2 :(得分:2)

就语法而言

_, _, var_needed, _, _, another_var_needed, _ = line.split()

是有效的python。我会说这甚至是惯用的,虽然有点不寻常。