0

I have a list of boxes defined by their coordinates and geometry as follows:

box = [x y w h]

I would like to loop through these boxes as shown below - problem is I need to change the boxes' representation in the function 'findMatchingbox) - so I boxes it to [xmin ymin xmax ymax] in this function. Problem is, when I give 'i' into the function in permanently changes the boxes in my list, I tried first letting a temp_i = i in the function, and then performing the necessary steps but to no avail.

I'm guessing it must be because python only keeps one copy of each box in memory, how would I send the specific box (i) into the function, extract the necessary information from it after transforming it, without changing the actual box? Can you make a copy of it?

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

Output:

1:   [464, 282, 48, 48]
2:   [464, 282, 512, 330]
3
  • I think it might be helpful to show a minimal example of the code in findMatchingBox Commented Mar 2, 2016 at 9:14
  • 1
    I think I actually figured it out: I have to make a temporary copy of i and do the calculations on that - I did this using temp_i = list(i). It doesnt work to simply say temp_i = i. Commented Mar 2, 2016 at 9:16
  • @Lafexlos same idea! Thanks Commented Mar 2, 2016 at 9:17

2 Answers 2

1

In python you have mutable and immutable objects.

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

If you want to change the values without changing the list everywhere, you need to copy it.

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

[1,2,3]

print(b)

[0,2,3]
Sign up to request clarification or add additional context in comments.

Comments

1

You need to clone the list before you modify it. So, if you want to change just this bit of code:

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)

However better would be to make 'findMatchingBox' clone its argument if it's going to modify it:

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

(it's always a bad idea to modify your arguments without cloning them, unless the modification is the point of the function.)

The reason that just saying:

temp_i = i

doesn't work, is that list objects in python are reference objects. (Think of them a bit like pointers in C if that helps).

It's rather unfortunate that python provides (so far) four ways to clone the list:

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

Note that with this particular example, copy and deepcopy behave the same - that wouldn't be the case if the list contained (eg) dicts rather than integers.

Personally I think the slice notation is most pythonic. Others may disagree.

1 Comment

you should also add deepcopy as copy won't work for nested lists because of shallow copying

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.