在python中使用这段代码有什么好处?(先设置i=[0],然后设置i[0]+=size)

2024-04-20 05:24:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在阅读一个使用了模块Theano的python脚本。我被下面的代码弄糊涂了。你知道吗

import numpy as np 
import theano.tensor as T
lparam = T.dvector('lparam')  # packed parameters
func = lambda expr: (theano.function([lparam],expr),expr)

i = [0]
def read_param(size):
    ret = lparam[i[0]:i[0]+size]
    i[0] += size
    return ret

函数read_param用于下面的函数中。你知道吗

N = 20
unpack_param, unpack_param_expr = func(T.stack(
    read_param(N),  # sigmoid energy
    read_param(N),  # sigmoid switching z
    T.exp(read_param(N)),  # sigmoid scale (>0)
    read_param(N),  # gaussian energy
    read_param(N),  # gaussian location
    T.exp(read_param(N))))  # gaussian scale (1/2sigma**2)


def pack_param(param):
    return np.concatenate((
        param[0],
        param[1],
        np.log(param[2]),
        param[3],
        param[4],
        np.log(param[5])), axis=0)

我被告知,它使用了“封闭”的概念,在写作和阅读上都很有优势。但我不知道为什么和如何运作。你知道吗


Tags: importreadsizereturnparamdefasnp
2条回答

我唯一的猜测是作者不想将i定义为全局变量:

i = 0
def read_param(size):
    global i
    ret = lparam[i:i+size]
    i += size
    return ret

我不知道为什么(也许作者对Python不太了解)。你知道吗

使用i[0]没有好处,只有缺点可读性差,占用CPU较多。你知道吗

这里的技巧是i是一个可变对象list,您可以对它进行变异,而不是重新赋值(这需要将它定义为global)。我会用一种更像马吕斯的答案中的Python式的方法。你知道吗

我认为作者认为这是一个很酷的把戏(虽然这个把戏很酷:def read_param(size, i=[0]):),并且会为他的方法辩护,但是The Zen of Python应该遵循:

  • 显性比隐性好。你知道吗
  • 简单胜于复杂。你知道吗
  • 可读性很重要。你知道吗
  • 特殊情况不足以打破规则。你知道吗
  • 面对模棱两可,拒绝猜测的诱惑。你知道吗
  • 应该有一种方法,最好只有一种明显的方法。你知道吗

我很难看出当前代码的优点。i被创建为一个列表,因此它可以在函数中进行变异,但是正如warvariuc所示,您可以使用global来实现同样的功能。你知道吗

下面是我将如何做同样的事情“pythonically”:

class ParamReader(object):
    def __init__(self, params):
        self.params = params
        self.i = 0

    def read(self, size):
        ret = self.params[self.i:(self.i + size)]
        self.i += size
        return ret

# Dummy values for lparam as I don't have theano
lparam = list(range(100))
reader = ParamReader(lparam)

reader.read(5)
Out[8]: [0, 1, 2, 3, 4]

reader.read(6)
Out[9]: [5, 6, 7, 8, 9, 10]

read函数必须维护state,因此使用一个简单的类似乎是一个明显的选择。你知道吗

相关问题 更多 >