0

我正在尝试创建一个函数 new_function,它将一个数字作为参数。此函数将根据我作为参数传递的数字来操作列表中的值。在这个函数中,我将放置另一个函数 new_sum,它负责处理列表中的值。例如,如果我将 4 传递给 new_function,我需要 new_function 对前四个元素中的每一个运行 new_sum。对应的值会改变,我需要新建四个列表。

例子:

listone=[1,2,3,4,5]
def new_function(value):
    for i in range(0,value):
        new_list=listone[:]
        variable=new_sum(i)
        new_list[i]=variable
        return new_list

# running new_function(4) should return four new lists
#    [(new value for index zero, based on new_sum),2,3,4,5]
#    [1,(new value for index one, based on new_sum),3,4,5]
#    [1,2,(new value for index two, based on new_sum),4,5]
#    [1,2,3,(new value for index three, based on new_sum),5]

我的问题是我不断得到一份巨大的清单。我究竟做错了什么?

4

2 回答 2

7

return修复语句的缩进:

listone=[1,2,3,4,5]
def new_function(value):
    for i in range(0,value):
        new_list=listone[:]
        variable=new_sum(i)
        new_list[i]=variable
    return new_list
于 2013-07-02T20:45:06.960 回答
2

The problem with return new_list is that once you return, the function is done.

You can make things more complicated by accumulating the results and returning them all at the end:

listone=[1,2,3,4,5]
def new_function(value):
    new_lists = []
    for i in range(0,value):
        new_list=listone[:]
        variable=new_sum(i)
        new_list[i]=variable
        new_lists.append(new_list)
    return new_lists

However, this is exactly what generators are for: If you yield instead of return, that gives the caller one value, and then resumes when he asks for the next value. So:

listone=[1,2,3,4,5]
def new_function(value):
    for i in range(0,value):
        new_list=listone[:]
        variable=new_sum(i)
        new_list[i]=variable
        yield new_list

The difference is that the first version gives the caller a list of four lists, while the second gives the caller an iterator of four lists. Often, you don't care about the difference—and, in fact, an iterator may be better for responsiveness, memory, or performance reasons.*

If you do care, it often makes more sense to just make a list out of the iterator at the point you need it. In other words, use the second version of the function, then just writes:

new_lists = list(new_function(4))

By the way, you can simplify this by not trying to mutate new_list in-place, and instead just change the values while copying. For example:

def new_function(value):
    for i in range(value):
        yield listone[:i] + [new_sum(i)] + listone[i+1:]

* Responsiveness is improved because you get the first result as soon as it's ready, instead of only after they're all ready. Memory use is improved because you don't need to keep all of the lists in memory at once, just one at a time. Performance may be improved because interleaving the work can result in better cache behavior and pipelining.

于 2013-07-02T20:58:50.010 回答