Python — Добавление «скрытых» значений в кортежи

#python

#python

Вопрос:

У меня есть набор кортежей, каждый из которых имеет три значения данных. Проблема, над которой я работаю, требует от меня кодирования четырех значений данных в каждом кортеже, но четвертое значение не должно учитываться при определении эквивалентности кортежей. Более формально,

 tuple1 = ('a', 'b', 'c', 'd')
tuple2 = ('a', 'b', 'c', 'f')

tuple1 == tuple2  # Should be true
  

Кроме того, если tuple1 было в наборе, tuple2 не может быть добавлено к этому набору

Каков наилучший способ реализовать это «скрытое» значение таким образом, чтобы это не повлияло на эквивалентность кортежей?

Я рассматривал возможность создания класса, который заключает в себе кортеж, и переопределения функций equal () и hash (), так что последний элемент не имеет значения в этом аспекте. Однако проблема, над которой я работаю, требует больших вычислительных затрат, и поэтому мне было интересно, есть ли более быстрые способы реализации этой функциональности.

Если вы знаете о каких-либо, пожалуйста, поделитесь. Спасибо.

Комментарии:

1. Насколько мне известно, встроенной функциональности нет.

2. Учитывая ваше требование размещать элементы в наборах, я думаю, вам придется написать свой собственный класс. Мне также любопытно посмотреть, есть ли другие способы, которыми это можно сделать.

3. Вы могли бы попробовать создать подкласс tuple , при этом ваше дополнительное значение будет помещено в слот экземпляра, а не в сам кортеж.

4. Что вы хотите получить на выходе {tuple1} | {tuple2} ? Должно ли это вызывать ошибку, и если нет, то какой кортеж «выигрывает»?

5. Что ж, если вы помещаете их в dicts, вам все равно придется решать эту проблему! (наборы — это просто dicts с нулевыми значениями)

Ответ №1:

Вы можете создать подкласс tuple и __new__ , используя комбинацию __init__ и,, создать кортеж, который также содержит 4-й атрибут в качестве отдельного атрибута. Я не знаю, насколько «похожим на кортеж» должно быть ваше решение, но это простое решение.

 class MyTuple(tuple):

    def __new__(cls, a, b, c, d):
        return super(MyTuple, cls).__new__(cls, (a,b,c))

    def __init__(self, a, b, c, d):
        self.d = d

    @property
    def as_tuple(self):
        return self   (self.d,)

    def __repr__(self):
        return 'Mytuple'   repr(self.as_tuple)

    def __str__(self):
        return str(self.as_tuple)


tuple1 = MyTuple('a', 'b', 'c', 'd')
tuple2 = MyTuple('a', 'b', 'c', 'f')

tuple3 = MyTuple('w', 'x', 'y', 'z')

my_dict = {tuple1:'one', tuple2:'two', tuple3:'three'}
print('hashed', my_dict)
  

Комментарии:

1. Я не нахожу идею убедительной. Преобразование неизменяемого типа в изменяемый кажется сложным. Кроме того, мы теперь переносим __dict__ на каждый экземпляр… хммм

2. Обычно помещение __slots__ = ['d'] в класс позволило бы избежать создания этого dict в каждом экземпляре — но, к сожалению, это не работает с кортежами (из-за их природы переменного размера).

3. @wim — наследование неизменяемого типа, возможно, не распространено, но, безусловно, имеет свое применение, и я не нахожу эту часть беспокоящей. Дополнительное пространство и дополнительное время, необходимые для создания экземпляра объекта, могут стать препятствием для сделки, но на современном оборудовании это должен быть значительный набор данных, прежде чем я буду беспокоиться. Есть много способов, которыми python может сжечь ваше ядро и съесть вашу оперативную память!

4. @jasonharper да, я был немного удивлен, когда TypeError: nonempty __slots__ not supported for subtype of 'tuple' появился в моей первой попытке.

5. Я не ограничен использованием кортежей. Пока структура данных является хэшируемой, все хорошо. Весь смысл в том, что я могу использовать tuple / MyTuple как отдельный ключ к хэш-таблице. Если tuple1 является ключом в словаре, то Dict[tuple2] должен возвращать то же значение, что и Dict[tuple1] .

Ответ №2:

Вместо того, чтобы думать о вашей проблеме как о наборе кортежей (каждый со скрытым значением), не могли бы вы представить это как сопоставление словаря заданному кортежу со скрытым значением?