【问题标题】:How to loop through a list of objects without changing the objects themselves?如何在不更改对象本身的情况下遍历对象列表?
【发布时间】:2016-03-02 17:25:04
【问题描述】:

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

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]

【问题讨论】:

  • 我认为在findMatchingBox中显示一个最小的代码示例可能会有所帮助
  • 我想我确实想通了:我必须制作 i 的临时副本并对其进行计算 - 我使用 temp_i = list(i) 进行了此操作。简单地说 temp_i = i 是行不通的。
  • @Lafexlos 同样的想法!谢谢

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


【解决方案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]

【讨论】:

    【解决方案2】:

    您需要先克隆列表,然后再对其进行修改。所以,如果你只想改变 这段代码:

    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(:)
        ....
    

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

    刚才说的原因:

    temp_i = i
    

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

    不幸的是,python(到目前为止)提供了四种克隆列表的方法:

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

    请注意,在此特定示例中,copydeepcopy 的行为相同 - 如果列表包含(例如)dicts 而不是整数,则情况并非如此。

    我个人认为切片符号是最 Pythonic 的。其他人可能不同意。

    【讨论】:

    • 您还应该添加deepcopy,因为复制不适用于嵌套列表,因为复制很浅
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 2021-08-06
    • 2014-06-09
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    相关资源
    最近更新 更多