Как создать динамически обновляемый список экземпляров класса, удовлетворяющий определенному условию?(Питон)
-
13-12-2019 - |
Вопрос
Я хочу создать список экземпляров классов, который автоматически обновляется в соответствии с определенным условием атрибутов экземпляра.
Например, у меня есть список объектов моего пользовательского класса Person(), и я хочу иметь возможность создать список, который всегда будет содержать всех лиц, состоящих в браке, т.е.все лица, имеющие атрибут «MAR_STATUS», равный «MARRIED».
Возможно ли это вообще в Python?Для микросимуляций я использовал прекомпилятор C++, в котором была очень удобная встроенная функция «actor_set», которая делала именно это.Но я понятия не имею, как это было реализовано на C++.
Спасибо.
Решение
список списка:
[person for person in people if person.MAR_STATUS == 'MARRIED']
.
Если вам нужно назначить его переменной, и вы хотите, чтобы эта переменная для автоматического обновления на каждом доступе вы можете поместить этот же код в Lambda, нормальную функцию или, если ваша переменная является классовым элементом, вСвойство Getter.
Другие советы
Бедная форма имеет «действие на расстоянии» / мутации / побочные эффекты, если оно не очень тщательно контролируется.
, который сказал, что императивный язык позволит вам сделать это, если вы действительно хотите, следующим образом.Здесь мы используем Python's [ Свойство Getbers и Getters ]:
MARRIED_SET = set()
def updateMarriedSet(changedPerson):
if hasattr(changedPerson,'married') and changedPerson.married==Person.MARRIED:
MARRIED_SET.add(changedPerson)
else:
MARRIED_SET.discard(changedPerson)
class Person(object):
...
@property
def married(self):
"""The person is married"""
return self._married
@married.setter
def married(self, newStatus):
self._married = newStatus
updateMarriedSet(self)
@married.deleter
def married(self):
del self._married
updateMarriedSet(self)
.
Я могу представить, что это может, возможно, быть полезным для обеспечения доступа к getMarriedpeople () запускается в o (1) время, а не амортизированное время o (1).
Самый простой способ — создать список «на лету», например, как показано в ответе @ sr2222.
В качестве альтернативы вы можете каждый раз вызывать произвольный обратный вызов. MAR_STATUS
изменения.Использовать __new__
если Person
экземпляры являются неизменяемыми или делают MAR_STATUS
а свойство и вызывать зарегистрированные обратные вызовы в методе установки (см. уведомления в черты библиотека для более сложной реализации).