2016-03-02 2 views
0

У меня есть список ящиков, заданных своими координатами и геометрии следующим образом:Как перебрать список объектов без изменения самих объектов?

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] 
+0

Я думаю, что это может быть полезно, чтобы показать минимальный пример кода в 'findMatchingBox' –

+1

boxTemp = поле [::]? – Lafexlos

+1

Я думаю, что я действительно понял это: мне нужно сделать временную копию i и выполнить вычисления на этом - я сделал это, используя temp_i = list (i). Это не работает, чтобы просто сказать temp_i = i. –

ответ

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

(это всегда плохая идея, чтобы изменить свои аргументы, не клонировать их, если модификация не является точкой функции)

причина, по которой только что говорил:.

temp_i = i 

не работает, это объекты списка в python являются ссылочными объектами. (Подумайте о них немного, как указатели на C, если это поможет).

Это довольно прискорбно, что питон обеспечивает (до сих пор) четыре способа клонировать списка:

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

Обратите внимание, что этот конкретный пример, copy и deepcopy ведут себя то же самое - что не было бы в случае, если список содержит (например) dicts, а не целые числа.

Лично я считаю, что нотация фрагмента является самой пифонической. Другие могут не согласиться.

+0

вы также должны добавить 'deepcopy', поскольку копия не будет работать для вложенных списков из-за мелкого копирования – danidee

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] 
Смежные вопросы