Допустим, у меня есть два set()
с:
a = {('1', '2', '3', 'a'), ('1', '2', '4', 'a'), ('1', '2', '5', 'b')}
b = {('1', '2', '3', 'b'), ('1', '2', '4', 'b'), ('1', '2', '6', 'b')}
Теперь я хочу найти разницу в множестве, b \ a
но проигнорировать последний элемент из каждого кортежа. Так что это как делать что-то вроде этого:
a = {('1', '2', '3'), ('1', '2', '4'), ('1', '2', '5')}
b = {('1', '2', '3'), ('1', '2', '4'), ('1', '2', '6')}
In[1]: b - a
Out[1]: {('1', '2', '6')}
Ожидаемый результат:
b \ a = {('1', '2', '6', 'b')}
Есть ли какой-нибудь очевидный / питонный способ достижения этого без необходимости вручную перебирать каждый набор и сверяться с каждым tuple[:3]
?
python
python-2.7
set
Грайдеану Алекс.
источник
источник
set
и перезаписать операцию разницы. Я не знаю готового решения, и я сомневаюсь, что оно существует.aa = { t[:3] for t in a }
tuple
и переопределить оператор разницыОтветы:
Вот как вы можете написать свой собственный класс для переопределения нормального поведения хэширования кортежа:
с выходом
Чтобы изменить поведение наборов кортежей, мы должны изменить способ хэширования кортежей.
Из здесь ,
Таким образом, чтобы хэширование игнорировало последний элемент, мы должны перегрузить методы dunder
__eq__
и__hash__
соответственно. Это не так сложно, потому что все, что нам нужно сделать, это отрезать последний элемент и затем делегировать его соответствующим методам нормалиtuple
.Дальнейшее чтение:
источник
:)
. На самом деле это просто объединение кусочков перегрузки операторов и того, как хеширование работает в Python.Вот один подход определения
a
иb
со списками , а не комплекты, так как мне кажется , что наиболее прямым решение предполагает индексациюb
:источник
Наборы работают нормально. Это ваши данные, которые не работают правильно. Если они выглядят по-разному, но на самом деле они одинаковы, тогда определите тип данных, который ведет себя так, как вы хотите. Тогда набор прекрасно работает сам по себе.
источник
__repr__
и__hash__
в терминах кортежей, но нет__eq__
. Не короче ли и здесь использовать кортежи? Фактически, вы можете использовать нарезку здесь и далее,__hash__
чтобы сократить код дальше.