Python - чудеса при работе с двумерным массивом. Меняются значения

5065584

Есть кусок кода:

i=0
while i <= (frame_number-1):
bonds_distances_fr=bonds_distances_str[i].split
leng=len(bonds_distances_fr)
bonds_distances_fr=bonds_distances_fr[1:]
print(bonds_distances_fr)
j=0
while j <= (bonds_number-1):
lij=float(bonds_distances_fr[j].strip
print lij
bonds_distances_all[i][j]=lij
print bonds_distances_all[i][j]
j=j+1
print
i=i+1
i=0
while i <= (frame_number-1):
j=0
while j <= (bonds_number-1):
print bonds_distances_all[i][j],
j=j+1
print
i=i+1

здесь bond_distances_str - список из frame_number строк. В первом цикле из него берется i-ая строка и разбивается в список bonds_distances_fr из (bonds_number+1) подстрок, в которых написаны числа. Затем из этого списка удаляется первый элемент. Во вложенном цикле каждая подстрока в списке bonds_distances_fr преобразуется в число с плавающей точкой lij, которе записывается в двумерный массив bonds_distances_all размером frame_number на bonds_number.
Вот здесь происходит странное. Судя по выводу операторов print из bond_distances_str правильно извлекается строка, которая правильно разбивается на подстроки, из получившегося списка правильно удаляется первый элемент, остальные элементы правильно преобразовываются в числа с плавающей точкой и правильно записываются в массив. Но следующие два вложенные цикла выводят все элементы того же массива, а в выводе значения только элементов его последней строчки.
Я не понимаю, где здесь может быть ошибка. Ведь с массивом ничего не делают между записью и выводом. В чем здесь может быть дело? Помогите, пожалуйста.

alfadred

Во-первых, этот кусок кода пишется значительно проще:
bonds_distances_all = [[float(x) for x in str.split[1:]] for str in bonds_distances_str]
(Формально он, конечно, делает не то же самое, но если формат правильный, то все хорошо)
А в исходном варианте покажи, как инициализируется bonds_distances_all, там может быть ошибка если ты присваиваешь один и тот же список в разные bonds_distances_all[i].

5065584


counter=1
for counter in range(bonds_number):
bonds.append(0)
line.append(0.0)
bonds_distances_average.append(0.0)
bonds_distances_deviation.append(0.0)
bonds_angles_average.append(0.0)
bonds_angles_deviation.append(0.0)
counter=counter+1
counter=1
while counter <= frame_number:
bonds_distances_all.append(line)
counter=counter+1

counter=firstframe
while counter <= lastframe:
bonds_on_frame.append(0)
bonds_angles.append(line)
bonds_distances.append(line)
counter=counter+1

Здесь сначала создается список чисел с плавающей точкой line длиной bond_number, потом они добавляются к списку bonds_distances_all frame_number раз. Так инициализируется двумерный массив

ppplva

Это ты зря. Читай предыдущий пост.

alfadred

Список - это объект, следовательно, присваивается по ссылке. Везде, где написано something.append(line поменяй на something.append(line[:]).
Если надо будет присваивать более сложные вещи, типа списков списков, используй copy.deepcopy: http://docs.python.org/library/copy.html

5065584

О, спасибо, проблема ушла. Просто я химик, и Питон не знаю.
Оставить комментарий
Имя или ник:
Комментарий: