Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
1 / 1 / 2
Регистрация: 12.07.2013
Сообщений: 146

Как определить структуру данных со своим in?

03.08.2013, 18:28. Показов 1798. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
еще проконсультируйте мну,
есть ли более менее стандартная реализация для такой структуры:
допустим объявляю класс, описываю его __eq__(self,y)
и надо мне такую структуру к-я бы для экземпляров моего класса:
1. предст. собой коллекцию - добавить, удалить по индексу, срез, чтение/изменение по индексу
2. имела функцию a in struct (проверка вхождения) к-я возвращала бы индекс(ы), если struct[indexes]==a

да, написать не сложно, ч/з map, я спрашиваю про "стандартную"...
или все таки наследовать лист и перекрывать in ?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.08.2013, 18:28
Ответы с готовыми решениями:

Как определить список через алгебраическую структуру данных?
Как определить список через алгебраическую структуру данных в haskell?

Как задать своим типам данных какие-нибудь операции (например сложение)?
Как задать своим типам данных какие-нибудь операции (например сложение), если это возможно?

Определить динамическую структуру данных стек
Определить динамическую структуру данных стек, поддерживающую функции добавления элемента, удаления элемента, вывода элементов стека на...

19
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
03.08.2013, 18:44
Цитата Сообщение от sabrus Посмотреть сообщение
имела функцию a in struct (проверка вхождения) к-я возвращала бы индекс(ы), если struct[indexes]==a
Семантически оператор `in` выполняет проверку вхождения элемента в коллекцию, а не возвращает ключи/индексы, по которым элемент находится в коллекции.

Ты, как я понял, хочешь что-то типа dict/list, у которых эта операция будет возвращаться все ключи/индексы? Насколько я знаю, такой коллекции нет, так что наследуй UserDict/UserList и переопределяй в нём метод __contains__. Хотя это не очень-то Pythonic-way.
0
1 / 1 / 2
Регистрация: 12.07.2013
Сообщений: 146
03.08.2013, 20:51  [ТС]
В принципе уже написал. Когда руки дойдут хочу в приличный вид привести, а то пока как раз и работает на словаре со значениями экземпляр-класса. Приходится циклить в поисках нужных элементов. А вот был бы in, было бы читабельнее.
Т.е проще говоря хочу такой Set к-ый понимал бы работу с экземплярами класса, т.е. чтобы можно было добавить одно к другому, вычесть, пересечь - ну стандартная логика множеств...с геометрией это было бы полезно - точки, ребра, полигоны...
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
03.08.2013, 22:01
Цитата Сообщение от sabrus Посмотреть сообщение
1. предст. собой коллекцию - добавить, удалить по индексу, срез, чтение/изменение по индексу
Цитата Сообщение от sabrus Посмотреть сообщение
Т.е проще говоря хочу такой Set к-ый понимал бы работу с экземплярами класса
в set нет индексов

Цитата Сообщение от sabrus Посмотреть сообщение
понимал бы работу
какую работу ?

Цитата Сообщение от sabrus Посмотреть сообщение
т.е. чтобы можно было добавить одно к другому
что добавить к чему ?

Цитата Сообщение от sabrus Посмотреть сообщение
В принципе уже написал.
и где там код ?
1
1 / 1 / 2
Регистрация: 12.07.2013
Сообщений: 146
03.08.2013, 22:31  [ТС]
код? он там. внутры.
да, индексов нет. итератор есть.
Работу? операции c множествами. объединение/сложение/пересечение/вычитание.
ну и операцию in
Только со своим типом. А не с числами, строками или кортежами.
В принципе логика операций над множествами со своим типом ничем не будет отличаться от реализованной в стандартной библиотеке. Если определены операторы отношений(больше меньше равно и т.д) для класса, что мешает выполнять например:

Python
1
2
3
4
5
6
a,b,c,d=MyClass(1,2,3), MyClass(1,2,3), MyClass(2,2,3), MyClass(2,2,3)
 
s1=set([a,d])
s2=set([c,d])
 
s1|=s2 # и все остальные операции с множествами
неужели эти вещи каждый раз пишутся заново?
Т.е. вопрос именно относительно множеств. А не коллекций. Логика работы(операции) с множествами весьма полезна в случаях когда работаешь со своим типом.
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
03.08.2013, 23:00
Цитата Сообщение от sabrus Посмотреть сообщение
Только со своим типом. А не с числами, строками или кортежами.
определи в своём типе __hash__ и используй set

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>>> class A:
...     def __init__(self, lst):
...         self._lst = lst
...     def __hash__(self):
...         return 0
...     def __eq__(self, a):
...         return self._lst == a._lst
...     def __repr__(self):
...         return '{}({})'.format('A', self._lst)
... 
>>> s1 = {A([1, 2, 3]), A([4, 5, 6])}
>>> s2 = {A([1, 1, 1]), A([2, 2, 2])}
>>> 
>>> union = s1 | s2
>>> print(union)
{A([4, 5, 6]), A([1, 2, 3]), A([2, 2, 2]), A([1, 1, 1])}
>>> print(union - {A([1, 1, 1])})
{A([4, 5, 6]), A([1, 2, 3]), A([2, 2, 2])}
>>>
1
1 / 1 / 2
Регистрация: 12.07.2013
Сообщений: 146
03.08.2013, 23:21  [ТС]
а объяснить? что дает __hash__-абельность?
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
03.08.2013, 23:28
делает объект вычисляемым; по идее, нужно уникальное число строить (инфа)
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
04.08.2013, 05:29
Объекты твоего класса перестали быть хешируемыми потому, что ты определил в нем операцию __eq__ (подробности по ссылке, которую дал accept выше), т.е., если ты определил __eq__, нужно определить и __hash__. Быстрый фикс — определить __hash__ через identity объекта:

Python
1
2
3
4
5
In [2]: class Klass:
   ...:     def __eq__(self, b):
   ...:         return id(self) == id(b)
   ...:     def __hash__(self):
   ...:         return id(self) # или hash(id(self))
Но по сути это будет правильным только в том случае, если и __eq__ определен через identity объекта (как в примере выше). Лучше определять __hash__ на основе данных, которые хранит класс.

Приведи уже код своего класса (и заодно скажи, должны ли быть данные твоего класса изменяемыми?).
1
1 / 1 / 2
Регистрация: 12.07.2013
Сообщений: 146
04.08.2013, 22:26  [ТС]
Цитата Сообщение от Nameless One Посмотреть сообщение
Приведи уже код своего класса (и заодно скажи, должны ли быть данные твоего класса изменяемыми?).
Я боюсь меня здесь просто "похоронят" с моим кодом. Буду сам разбираться, и спасибо за помощь.

Добавлено через 3 минуты
Цитата Сообщение от Nameless One Посмотреть сообщение
т.е., если ты определил __eq__, нужно определить и __hash__. Быстрый фикс — определить __hash__ через identity объекта
я еще ничего не определял. я пока только интересуюсь реализацией...
и Спасибо.

Добавлено через 12 часов 54 минуты
допустим пишу что то такое:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# -*- coding CP1251 -*-
 
class Pt:
    def __init__(self,x,y):
        self.x=x
        self.y=y
 
    def __eq__(self,y):
        return (self.x==y.x) and (self.y==y.y)
 
    def __repr__(self):
        return '({},{})'.format(self.x,self.y)
 
class Rib:      
    def __init__(self,pt1,pt2):
        self.pt1=pt1
        self.pt2=pt2
        self.mf=set()
        self.olf=set()
 
    def __hash__(self):
        return 0
    
    def __eq__(self,r2):
        return (self.pt1==r2.pt1) and (self.pt2==r2.pt2)
 
    def __repr__(self):
        return '{}({}-{})-({})'.format('Rib', self.pt1,self.pt2,self.mf)
 
a=Rib(Pt(1,1),Pt(2,3))
a.mf={1,2}
b=Rib(Pt(1,1),Pt(2,4))
 
c=Rib(Pt(1,1),Pt(2,3))
c.mf={0,1}
d=Rib(Pt(1,1),Pt(2,4))
 
s1=set([a,b])
s2=set([c,d])
 
print(s1==s2)
s1|=s2
 
for rib in s1:
    print(rib, end='\n')
 
print(c in s1)
print(c)
т.е. при проверке вхождения ребра в множество используется только сравнение точек начала-конца(__eq__), если true ребро при операции |= не добавляется, иначе добавляется.
наличие __hash__ в классе позволяет по полям задействованным в __eq__ идентифицировать значения и соотв. использовать их как допустимый тип для операций с set-ами. Пока правильно или уже нет?
Возможно ли путем магических методов сделать такую логику:
если __eq__ для пары ребер будет true, то чтобы до рассмотрения следующих пар ребер, c данной парой выполнялась некая работа?
В примере - чтобы при рассмотрении а==с в итоговом множестве поле .mf элемента было объединением соотв. полей ребер а и с, т.е. результат был бы:
Rib((1,1)-(2,3))-({1, 2, 0})
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
04.08.2013, 23:39
Цитата Сообщение от sabrus Посмотреть сообщение
Возможно ли путем магических методов сделать такую логику:
если __eq__ для пары ребер будет true, то чтобы до рассмотрения следующих пар ребер, c данной парой выполнялась некая работа?
какая работа ?

Цитата Сообщение от sabrus Посмотреть сообщение
В примере - чтобы при рассмотрении а==с в итоговом множестве поле .mf элемента было объединением соотв. полей ребер а и с
Цитата Сообщение от sabrus Посмотреть сообщение
в итоговом множестве поле .mf элемента
в каком итоговом множестве ?
какого элемента ?
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.08.2013, 05:44
Цитата Сообщение от sabrus Посмотреть сообщение
наличие __hash__ в классе позволяет по полям задействованным в __eq__ идентифицировать значения и соотв. использовать их как допустимый тип для операций с set-ами. Пока правильно или уже нет?
Нет, этого недостаточно. Значение __hash__ должно возвращать некоторое число, причем hash(Edge1) == hash(Edge2) тогда и только тогда, когда Edge1 == Edge2.

Вот пример реализации для твоих классов:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# -*- coding: utf-8 -*-
#!/usr/bin/env python3
 
class Point:
    def __init__(self, x, y):
        self.x, self.y = x, y
 
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
 
    def __hash__(self):
        return hash((self.x, self.y))
 
    def __repr__(self):
        return '({x},{y})'.format(x=self.x, y=self.y)
 
class Edge:
    def __init__(self, pt1, pt2):
        self.pt1, self.pt2 = pt1, pt2
 
    def __eq__(self, other):
        return self.pt1 == other.pt1 and self.pt2 == other.pt2
 
    def __hash__(self):
        return hash((self.pt1, self.pt2))
 
    def __repr__(self):
        return 'Edge({pt1}-{pt2})'.format(pt1=self.pt1, pt2=self.pt2)
Поля .mf и .olf я не трогал, т.к. не понимаю их назначение (кстати, так именовать переменные — плохо). Но, как я понимаю, они в сравнении и в хешировании участвовать не должны.

Python
1
2
3
4
5
6
7
8
9
10
11
>>> x = Point(1, 2)
>>> y = Point(2, 2)
>>> Edge(x, y) == Edge(x, x)
False
>>> Edge(x, y) == Edge(x, y)
True
>>> Edge(x, y) in {Edge(x, y)}
True
>>> Edge(x, x) in {Edge(x, y)}
False
>>>
Следует отметить, что при такой реализации два ребра будут считаться различными, если порядок их точек будет различаться, даже если эти точки попарно равны. Например:
Python
1
2
3
4
5
>>> Edge(x, y) == Edge(y, x)
False
>>> Edge(x, y) in {Edge(y, x)}
False
>>>
Если тебя не устраивает такое поведение, то нужно изначально хранить точки ребра отсортированными (например, лексикографически).

Цитата Сообщение от sabrus Посмотреть сообщение
Возможно ли путем магических методов сделать такую логику:
если __eq__ для пары ребер будет true, то чтобы до рассмотрения следующих пар ребер, c данной парой выполнялась некая работа?
В примере - чтобы при рассмотрении а==с в итоговом множестве поле .mf элемента было объединением соотв. полей ребер а и с, т.е. результат был бы:
Rib((1,1)-(2,3))-({1, 2, 0})
Можно, хотя такое поведение может быть неочевидным для пользователя.
0
1 / 1 / 2
Регистрация: 12.07.2013
Сообщений: 146
05.08.2013, 14:13  [ТС]
"при такой реализации два ребра будут считаться различными" - да это я знаю, я пример натягивал чтобы обрисовать ситуацию. Для примера это не играет.
Именование переменных тоже для примера.
mf -master faces - грани к-м принадлежит ребро
olf - overlappped faces - грани которые потенциально содержат (по габ тесту) это ребро

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

Добавлено через 2 часа 35 минут
"Можно, хотя такое поведение может быть неочевидным для пользователя."
- как? создавать класс MySet(set)? переопределять операции? "Модифицировать" стандартную реализацию не получится?
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.08.2013, 16:07
Цитата Сообщение от sabrus Посмотреть сообщение
"Можно, хотя такое поведение может быть неочевидным для пользователя."
- как? создавать класс MySet(set)? переопределять операции? "Модифицировать" стандартную реализацию не получится?
Если ты хочешь, чтобы при ручном сравнении a == b изменялось поле .mf объекта a, то просто засунь это в реализацию __eq__; если же ты хочешь, чтобы это выполнялось при проверке, принадлежит ли ребро множеству (a in SetOfEdges), то вынужден тебя огорчить, тут ничего не получится, т.к. при такой проверке метод сравнения __eq__ не вызывается.
0
1 / 1 / 2
Регистрация: 12.07.2013
Сообщений: 146
05.08.2013, 18:22  [ТС]
да, есть хэш-значение, зачем еще что-то вызывать,
т.е реализовать такое поведение кроме как перебром по циклу с условием if a in set нельзя?
Ну, и всегда есть вариант своего класса с определением требуемой логики...(долгая дорожка...)
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
05.08.2013, 18:33
Цитата Сообщение от Nameless One Посмотреть сообщение
# -*- coding: utf-8 -*-
в третьем питоне уже несколько лет кодировка по умолчанию - utf-8

Цитата Сообщение от Nameless One Посмотреть сообщение
Python
9
        return self.x == other.x and self.y == other.y
Python
9
        return (self.x, self.y) == (other.x, other.y)
Цитата Сообщение от Nameless One Посмотреть сообщение
то нужно изначально хранить точки ребра отсортированными
во множестве нужно хранить, если пара неупорядоченная

Цитата Сообщение от Nameless One Посмотреть сообщение
то просто засунь это в реализацию __eq_
не надо ничего лишнего вставлять в метод сравнения
метод сравнения, меняющий объект сравнения, - это костыль, из-за которого потом что-нибудь сломается

если такое нужно делать, то это делается отдельным методом
нужно задать вопросы:
1) понадобится ли когда-нибудь сравнивать рёбра без слияния граней ?
2) всегда ли надо будет сливать грани рёбер при сравнении рёбер ?

да и почему точки на плоскости, а речь про грани идёт ? какой смысл имеет сравнение точек с разных граней ?
0
1 / 1 / 2
Регистрация: 12.07.2013
Сообщений: 146
05.08.2013, 18:48  [ТС]
Но ведь можно наследовать set, и перекрыть код требуемого метода, в данном случае .union? Я прав?

Добавлено через 5 минут
Алгоритм динамический. Изначальные ребра предст. собой проекции 3д граней, естественно некотрые грани закрывают друг друга, и соотв. проекции пересекаются, алгоритм из начального набора ребер, динамически образует новый, где каждое ребро уже ни с чем не пересекается, и попутно определяет насколько видимо это ребро(обратный луч и определение Z для данного ребра по каждой из olf)(с этой целью каждое ребро имеет "историю происхождения" т.е. путем перекрытия каких граней должна определяться его глубина видимости(olf), и к какому начальному полигону проекции оно принадлежит("хозяев" м.б. несколько, т.е. ребро одной грани закрывает ребро другой грани)).В начале в olf каждого ребра только номер грани-"первого хозяина", в дальнейшем ребро распадается на участки, и добавляются новые грани к-е закрывают/закрыты данную/данной...
пардон,сумбурно.

Добавлено через 6 минут
т.е. на плоскости и на центральном процессоре(да,да...я знаю кто я). решается задача представления проекции 3д сцены.
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.08.2013, 18:57
Цитата Сообщение от accept Посмотреть сообщение
в третьем питоне уже несколько лет кодировка по умолчанию - utf-8
Я не только третий питон использую, да и Emacs у меня сам эту строку вставляет.

Цитата Сообщение от accept Посмотреть сообщение
во множестве нужно хранить, если пара неупорядоченная
Да, пожалуй, так будет лучше.

Цитата Сообщение от accept Посмотреть сообщение
не надо ничего лишнего вставлять в метод сравнения
Ну я тоже говорил, что так делать не хорошо.

Цитата Сообщение от sabrus Посмотреть сообщение
и перекрыть код требуемого метода, в данном случае .union?
Так, а зачем теперь нужно переопределять union?
0
1 / 1 / 2
Регистрация: 12.07.2013
Сообщений: 146
05.08.2013, 19:02  [ТС]
ятд в union производного класса я должен переопределять "свое" поведение? если речь о слиянии множеств, я не прав?
Если как вы сказали ранее -
стандартную реализацию set методом магических методов нельзя привести к такому поведению:
чтобы сравнение производилось на основании хеша не всех полей моего типа, и в случае если __eq__=true, выполнить свою логику...а не перейти сразу к следующей паре претендентов на слияние...
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.08.2013, 19:18
Цитата Сообщение от sabrus Посмотреть сообщение
ятд в union производного класса я должен переопределять "свое" поведение? если речь о слиянии множеств, я не прав?
Что такое "ятд"? Я тебя не понимаю.

Цитата Сообщение от sabrus Посмотреть сообщение
стандартную реализацию set методом магических методов нельзя привести к такому поведению:
чтобы сравнение производилось на основании хеша не всех полей моего типа, и в случае если __eq__=true, выполнить свою логику...а не перейти сразу к следующей паре претендентов на слияние...
Напиши псевдокод с подробными комментариями, что ты хочешь сделать.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.08.2013, 19:18
Помогаю со студенческими работами здесь

Как установить соединение со своим сайтом? Как установить связь с базой данных mysql?
Читаю книгу по Node.js, но понимаю там ооочень много воды, которая мне не нужна и это только путает. Хочу спросить. Как установить...

Исходя из условия задачи, определить структуру комбинированного типа данных
P.S-заголовок:Исходя из условия задачи, определить структуру комбинированного типа данных и типа полей. Исходные данные разместить в...

Определить структуру данных, поддерживающую функции добавления, удаления и вывода элементов
Помогите написать код: Определить динамическую структуру данных – отсортированный однонаправленный список, поддерживающую функции...

Описать структуру (запись - record) согласно варианту, определить типы данных полей
Написать программу , которая реализует географический справочник . В справочнике содержится следующая информация : название страны и...

Определить структуру, описывающую сведения о игрушках, написать и протестировать функции ввода и вывода данных
Доброго времени суток. Столкнулась со структурами и так и не смогла разобраться( Помогите пожалуйста. Сама задача: Определить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru