Pythonic方法用于创建列表的临时副本

时间:2015-11-25 18:41:14

标签: python list python-3.x copy

是否有更多的Pythonic方式来执行以下操作(请原谅半伪代码)?

from copy import deepcopy
# Create a copy of a list edit an element within it
# then run a function using the new copy of the list
actuallist = [some data]
answer = 0
for i in len(actuallist):
    temp = deepcopy(actuallist)
    temp[i] = temp[i] + something
    tempplus = DoSomething(temp)
    temp = deepcopy(actuallist)
    temp[i] = temp[i] - something
    tempminus = DoSomething(temp)
    answer += OneMoreThing(tempplus, tempminus)

1 个答案:

答案 0 :(得分:0)

如果DoSomething没有改变列表,你可以这样做:

answer = 0
for i in len(actuallist):
    tempplus = DoSomething(actuallist[:i] + [actuallist[i] + something] + actuallist[i+1:])
    tempminus = DoSomething(actuallist[:i] + [actuallist[i] - something] + actuallist[i+1:])
    answer += OneMoreThing(tempplus, tempminus)

但无论我们是使用列表的深层副本还是仅使用切片,我们都应该将该常用功能捆绑到一个函数中:

def shift(target, index, shift_value):
    return target[:index] + [target[index] + shift_value] + target[i+index:]

answer = 0
for i in len(actuallist):
    tempplus = DoSomething(shift(actuallist, i, something))
    tempminus = DoSomething(shift(actuallist, i, -something))
    answer += OneMoreThing(tempplus, tempminus)

此时我们可以将该循环重写为:

answer = 0
for i in len(actuallist):
    answer += OneMoreThing(
        DoSomething(shift(actuallist, i, something)),
        DoSomething(shift(actuallist, i, -something))
    )

此时,您可以使用sum进行求和,将其重写为生成器表达式。

answer = sum(OneMoreThing(
    DoSomething(shift(actuallist, i, something)),
    DoSomething(shift(actuallist, i, -something))
) for i in len(actuallist))

虽然这有点太多了。我可能会建议使用其他功能。

我根据您提供的通用示例名称不了解您的功能的性质,因此我无法确定如何最好地对此进行分组。你可以这样做:

def shift(target, index, shift_value):
    return target[:index] + [target[index] + shift_value] + target[i+index:]

def one_more_thing_for_index(actuallist, i, something):
    return OneMoreThing(
        DoSomething(shift(actuallist, i, something)),
        DoSomething(shift(actuallist, i, -something))
    )

answer = sum(one_more_thing_for_index(actuallist, i, something)
             for i in len(actuallist))

使用这些非常通用的名称,我认为这实际上可能不如你的例子清楚。但是,我认为您可以为您的特定问题域选择一些逻辑名称,以使其更加自我记录。