необъяснимая проблема с питоном - PullRequest
1 голос
/ 03 января 2011

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

class dbase:
    def __init__(self):
        self.rows = {}
        self.cols = {}
    def addrow(self, name):
        self.rows[name] = self.cols
    def addcol(self, name):
        for x in self.rows:
            self.rows[x][name] = None
    def printit(self):
        for x in self.rows:
            print x, self.rows[x]
a = dbase()
a.addrow("coke")
a.addcol("price")
a.printit()
a.addrow("sprite")
a.printit()

хорошо, вот странная вещь.моя программа печатает строку спрайта как имеющую внутренний словарь со значением «цена», но нигде в моей программе я не сказал self.cols ["price"] = Нет, так как функция addrow для sprite помещает в нее этот внутренний словарь?спасибо за любую помощь

Ответы [ 6 ]

4 голосов
/ 03 января 2011

Ничего себе. Это самый грязный код, который я видел за последнее время. Вы понимаете, что когда вы добавляете строку, вы просто добавляете тот же словарь, что и в каждом другом столбце.

def __init__(self):
    self.rows = {}
    self.cols = {}
def addrow(self, name):
    self.rows[name] = self.cols

Я думаю, вы имели в виду

def addrow(self, name):
    self.rows[name] = {}
2 голосов
/ 03 января 2011

Каждому значению в self.rows присваивается self.cols, поэтому они совместно используют тот же словарь, что и ключ.Если вы измените self.rows[x], то вы также измените self.rows[y], потому что это один и тот же объект .Точно так же, если вы затем добавите self.cols в качестве значения для self.rows[z], у него будет все то же содержимое, потому что это все тот же объект.грести каждый раз, затем сделать это : назначить {}.

Но для этого вам вообще не нужен класс;это просто подталкивает вас к использованию пользовательского интерфейса для чего-то, что естественно делается прямо в Python.Вы, вероятно, также должны смотреть на collections.defaultdict.

1 голос
/ 03 января 2011

При вызове a.addcol("price") код изменяет self.rows[x][name], устанавливая его равным None.

self.cols, таким образом, устанавливается равным dict {'price': None}.Поскольку каждый self.rows[x] установлен равным self.cols, вы каждый раз печатаете один и тот же дикт.

0 голосов
/ 03 января 2011

Самый простой способ сделать это - просто получить список словарей.Например:

# A new "database"
dbase = []
# Adding a new "row".
dbase.append({})
# Adding columns to a specific row:
dbase[0]['newcol'] = "The value"
# Retrieving a colum from a row which will raise a KeyError if the column doesn't exist:
dbase[0]['newcol']
# Retrieving a colum from a row which will return None if the column doesn't exist:
dbase[0].get('anothercol')

Также вы можете посмотреть DefaultDict, но я думаю, что лучше сначала узнать, как работают стандартные словари и объекты.

0 голосов
/ 03 января 2011

Вы постоянно используете один и тот же экземпляр словаря.

def addrow(self, name):
    self.rows[name] = self.cols

Помните, что Python похож на Java, когда дело доходит до переменных - каждое имя является просто ссылкой на экземпляр объекта. Это не так, как в C, где присвоение переменной почти всегда означает копирование значение.

Если вы хотите создать табличный класс quick-n-dirty для строк и столбцов, вы можете использовать defaultdict, например:

from collections import defaultdict

class RowsAndColumns:
    def __init__(self):
        self._rows = defaultdict(dict)

    def get(self, row, col):
        return self._rows[row][col]

    def set(self, row, col, value):
        self._rows[row][col] = value

matrix = RowsAndColumns()
matrix.set("Coke", "Price", 1.99)
print matrix.get("Coke", "Price") # 1.99
print matrix.get("Pepsi", "Price") # KeyError "Price"
0 голосов
/ 03 января 2011

Когда вы настраиваете столбцы для строки, вы всегда ссылаетесь на self.cols - поскольку Python обрабатывает это как ссылку, каждый раз, когда вы обновляете его, вы обновляете его для всего, что указывает на эту ссылку.

Вам следует каждый раз инициализировать его соответствующим значением, если вы ожидаете различный набор столбцов для каждой строки.

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