Python 2-мерный массив ведет себя странно - PullRequest
1 голос
/ 28 февраля 2012

Я пытался перенести программу, написанную на C ++, на Python.В частности, это программа для создания карт высот, которые можно экспортировать в 3D-модели и которые в идеале при просмотре выглядят как реалистичный ландшафт.

Класс HeightMap оборачивает двумерный массив значений с плавающей точкой.На данный момент я сохранил его как целые числа, потому что он печатает лучше, и у меня не было возможности реализовать какие-либо другие функции.У меня проблема в том, что когда я вызываю set (self, x, y, value), который просто устанавливает значение в x, y в значение с кодом «self.rows [y] [x] = value»Кажется, он изменяет весь столбец, посещая каждый элемент self.rows и устанавливая значение для x-го элемента этого массива.

Вот мой код.Я примерно на 90% уверен, что ошибка где-то в инициализации 2-х массивов.

def filledArray(length, value) :
    result = []
    for i in range(1, length) :
        result.append(value)
    return result

def resizeArray(array, newLength, nullValue) :
    if newLength == len(array) :
        return array
    result = []
    for i in range(0, newLength) :
        if i < len(array) :
            result.append(array[i])
        else :
            result.append(nullValue)
    return result

class HeightMap:
    """A class that wraps a 2D array for generating height maps"""
    def __init__(self) :
        self.width = 0
        self.height = 0
        self.rows = []

    def __init__(self, initWidth, initHeight) :
        self.clear(initWidth, initHeight);

    def clear(self, initWidth, initHeight) :
        self.width = initWidth
        self.height = initHeight
        self.rows = filledArray(initHeight, filledArray(initWidth, 0))

    def setHeight(self, newHeight) :
        if self.height == newHeight :
            return
        self.rows = resizeArray(self.rows, newHeight, filledArray(self.width, 0))

    def setWidth(self, newWidth) :
        if self.width == newWidth :
            return
        for i in range(0, len(self.rows)) :
            self.rows[i] = resizeArray(self.rows[i], newWidth, 0);
        self.width = newWidth

    def get(self, x, y) :
        return self.rows[y][x]

    def set(self, x, y, value) :
        self.rows[y][x] = value

    def add(self, x, y, value) :
        self.rows[y][x] += value

    def multiply(self, x, y, value) :
        self.rows[y][x] *= value

1 Ответ

2 голосов
/ 28 февраля 2012

Ваша проблема в том, что при вызове filledArray(initHeight, filledArray(initWidth, 0)) второй аргумент передается по ссылке (это всегда имеет место с объектами python).Внутри filledArray вам нужно сделать копию value для каждого.Это потребует добавления немного дополнительной логики к вашей функции, что-то вроде:

if type(value) == list:
   value = list(value)

Или вы можете сделать чуть менее pythonic:

type(value)(value)

, чтобы создатькопия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...