如何循环访问对象列表而不更改对象本身?

时间:2016-03-02 09:10:59

标签: python python-3.x python-3.5

我有一个由其坐标和几何定义的框列表,如下所示:

box = [x y w h]

我想循环遍历这些框,如下所示 - 问题是我需要在函数'findMatchingbox中更改框的表示 - 所以我在这个函数中将它设置为[xmin ymin xmax ymax]。问题是,当我将“i”赋予函数永久更改列表中的框时,我首先尝试在函数中放置temp_i = i,然后执行必要的步骤但无济于事。

我猜它一定是因为python只保留每个盒子的一个副本在内存中,我如何将特定的盒子(i)发送到函数中,在转换后从中提取必要的信息,而不改变实际框?你能复制一份吗?

for i in bboxes:
    # Determine if detection belongs to an existing object
    print('1:\t',i)
    boxIDx = self.findMatchingBox(i)
    print('2:\t')

输出:

1:   [464, 282, 48, 48]
2:   [464, 282, 512, 330]

2 个答案:

答案 0 :(得分:1)

您需要在修改列表之前克隆该列表。所以,如果你想改变 这段代码:

for i in bboxes:
    # Determine if detection belongs to an existing object
    print('1:\t', i)
    box = i(:)
    boxIDx = self.findMatchingBox(box)
    print('2:\t', i)

然而,更好的方法是让'findMatchingBox'克隆它的参数,如果它要修改它:

def findMatchinBox(self, box)
    box = box(:)
    ....

(修改你的参数而不克隆它们总是一个坏主意,除非修改是函数的 point 。)

原因只是说:

temp_i = i

不起作用,是python中的列表对象是引用对象。 (如果有帮助的话,可以把它们想象成C中的指针)。

令人遗憾的是,python(迄今为止)提供了四种克隆列表的方法:

temp_i = list(i)
temp_i = i.copy()
temp_i = i.deepcopy()
temp_i = i[:]

请注意,对于此特定示例,copydeepcopy的行为相同 - 如果列表包含(例如)dicts而不是整数,则不会出现这种情况。

就我个人而言,我认为切片符号最为pythonic。其他人可能不同意。

答案 1 :(得分:1)

在python中你有mutable and immutable objects

a = [1,2,3]
b = a
b[0] = 0
print(a)
[0,2,3]

如果要更改值而不在任何地方更改列表,则需要复制它。

a = [1,2,3]
b = a.copy()
b[0] = 0
print(a)

[1,2,3]

print(b)

[0,2,3]