在隐式调用的函数中向列表追加内容

2 投票
2 回答
1572 浏览
提问于 2025-04-18 07:21

在这段代码中,generate() 函数是被另一个函数隐式调用的。

问题是,下面的代码中有没有办法确保当 generate() 函数被调用四次时,b 的值能够保存在列表 p 中,而不是替换掉之前已经添加的元素。目前,列表 t 里只添加了一个 b 的值。

    import random as rand 
    f = [1,2,3,4]
    k = rand.choice(f)
    h = rand.choice(f)


    def generate():

        global b # declare b as global

        t = []
        b = k + h
        t.append(b) #Append b to all so that
        print 'all:',t

        c = 4**2

        return c

generate()


def evaluate():

    fit = (generate() * b) # generate() is used here

    print "fit:", fit

    # Some other expressions using variable b
    p = []
    for i in range(4):
        p.append(b)
    print 'p:',p

    return fit

evaluate()


#output
all: [3]
fit: 48
p: [3, 3, 3, 3]

2 个回答

1

这里的 t 需要是全局变量...

当然,它只有一个元素,你可以先把它初始化为空,然后再往里面添加一个项目...而且它只在 generate 函数内部可用...

另外,你想通过 generate 函数实现什么并不太清楚(通常它会返回一个新的个体...)

你可以这样修改,让 t 获取所有的 b ...

t = []
def generate():
    global b # declare b as global
    b = k + h
    t.append(b) #Append b to all so that
    print 'all:',t
    c = 4**2
    return c

不过我怀疑你还有很多其他问题。

3

我觉得你遇到了作用域的问题。可以看看下面的链接,了解一下Python中的作用域是什么,并考虑这个例子:

>>> results = []
>>> i = [0]
>>> def test():
...     i[0] = random.randint(0, 100)
...     print i
...     results.append(i)
...
>>> test()
[20]
>>> test()
[99]
>>> test()
[18]
>>> results
[[18], [18], [18]]

注意,虽然每次调用test()时,i[0]的值会变化,但我们每次都在把同一个列表i添加到results中。因此,当i中的某个元素发生变化时,这个变化会在results列表中反映出来。

链接:

Python作用域规则的简短描述?

https://www.inkling.com/read/learning-python-mark-lutz-4th/chapter-17/python-scope-basics

编辑

要解决上面的问题,你需要确保在每次调用test()时,不要覆盖同一个列表。你可以通过每次创建一个新列表,或者在修改之前复制这个列表来做到这一点。

>>> import copy
>>> def test():
...     j = copy.copy(i)
...     j[0] = random.randint(0, 100)
...     print j
...     results.append(j)
...
>>> results = []
>>> test()
[75]
>>> test()
[13]
>>> test()
[17]
>>> results
[[75], [13], [17]]

你提到你在处理嵌套列表,这种情况下你应该使用copy.deepcopy而不是copy.copy。深拷贝会复制列表中的所有元素以及列表本身。

撰写回答