Использование экземпляров класса, удовлетворяющих нескольким условиям, без списков

#python #list #class

Вопрос:

Я хочу знать, как найти экземпляры класса, которые удовлетворяют некоторым условиям, и использовать их без применения списков python.

 class d1():
    def __init__(self,a,b):
        self.a=a
        self.b=b
f0=d1(2,1)
f1=d1(2,3)
f2=d1(2,4)
f3=d1(4,4)
 

В этом случае я хочу найти экземпляры, в которых есть a==2 и b<4 ( f0 и f1 ), и использовать их без применения списков python. Я хочу знать, как они решаются на других языках, в которых нет таких блоков, как списки python.

Итак, есть 2 вопроса:

  1. поиск экземпляра с несколькими условиями
  2. работа с объектами без использования списков python.

Списки Python динамичны, в них можно помещать все, что угодно, но в других языках, таких как C, нет ничего подобного, так как же был бы ответ, если бы этот вопрос был задан на этих других языках, каков его эквивалент в python?

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

1. Не могли бы вы уточнить, что вы подразумеваете под «использовать их, если они не являются списками python» ? Переменные f0 и f1 уже не являются списками, верно?

2. списки python — это динамический список, в который вы можете поместить что угодно, но в других языках, таких как c, нет ничего подобного, так что там рассматривается ответ на этот вопрос и что эквивалентно в python.

3. @NielGodfreyPonciano они являются экземплярами класса d1, верно?

4. Если количество экземпляров, которые вы создадите, не фиксировано, поэтому оно может вырасти с 4 до 1000 или даже более бесконечно, тогда нам нужно разработать структуру данных, которая может изменяться сама по себе, либо перераспределяться в другой блок памяти большего размера, либо порождать другой блок, чтобы поместить только дополнительные элементы. Но зачем нам это делать, если у нас уже есть встроенные модули, такие как list . Итак, вкратце , если вам не нравится list , мы должны переопределить нашу собственную list структуру данных 🙂

5. @FarhangAmaji Я обновил свой ответ, чтобы поддержать любое условие. Возможно, это лучше подходит для того, что вам нужно, чем мой предыдущий ответ, в котором использовалось фиксированное условие.

Ответ №1:

Для простоты я добавил __str__ метод для более читаемой печати. Вам необходимо использовать встроенную функцию globals для доступа к словарю глобальной области действия программы. Я не думаю, что это хорошая практика для начала, но… вот код.

 class d1():
    def __init__(self,a,b):
        self.a=a
        self.b=b
    def __str__(self):
        return f'{self.a} {self.b}'

f0=d1(2,1)
f1=d1(2,3)
f2=d1(2,4)
f3=d1(4,4)
   
d1_list = [f for k, f in globals().items() if isinstance(f, d1)]

print([print(f) for f in d1_list if f.a == 2 and f.b < 4]) # you can omit the internal print
 

Выход

 2 1
2 3
[None, None] # it is a consequence of the __str__
 

Ответ №2:

  1. Создайте новый экземпляр d1
  2. Вы можете выбрать либо:

    a. Получите ссылку на сам объект

    б. Получите слабую ссылку на объект. Преимущество этого заключается в том, что ссылка не сохранит объект живым, если его уже можно удалить.

  3. Чтобы не использовать list контейнеры фиксированного размера или любые другие контейнеры, используйте связанный список d1._instances (атрибут класса), где мы добавляли бы каждый новый экземпляр в конец связанного списка.
  4. Чтобы упростить d1._instances итерацию , сделайте ее повторяемой.
  5. Отфильтруйте экземпляры, удовлетворяющие данному условию.
 import weakref


class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

    def __iter__(self):
        current = self
        while current:
            yield current.value()  # Operation () is to access the value of the weak reference
            current = current.next


class d1:
    _instances = None
    _instances_tail = None

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

        self._store_instance()

    def _store_instance(self):
        current = Node(weakref.ref(self))  # Or just <Node(self)> if you choose 2.a above
        if not self._instances:
            d1._instances = current
        else:
            d1._instances_tail.next = current
        d1._instances_tail = current

    @staticmethod
    def get_instances(condition=lambda value: True):  # Default behavior is get everything
        return filter(condition, d1._instances)


f0=d1(2,1)
f1=d1(2,3)
f2=d1(2,4)
f3=d1(4,4)

print("nall")
for instance in d1.get_instances():
    print(type(instance), instance.a, instance.b)

print("na == 2 and b < 4")
for instance in d1.get_instances(condition=lambda value: value.a == 2 and value.b < 4):
    print(type(instance), instance.a, instance.b)

print("na == 2 and b >= 3")
for instance in d1.get_instances(condition=lambda value: value.a == 2 and value.b >= 3):
    print(type(instance), instance.a, instance.b)

print("na == 4")
for instance in d1.get_instances(condition=lambda value: value.a == 4):
    print(type(instance), instance.a, instance.b)
 

Выход

 all
<class '__main__.d1'> 2 1
<class '__main__.d1'> 2 3
<class '__main__.d1'> 2 4
<class '__main__.d1'> 4 4

a == 2 and b < 4
<class '__main__.d1'> 2 1
<class '__main__.d1'> 2 3

a == 2 and b >= 3
<class '__main__.d1'> 2 3
<class '__main__.d1'> 2 4

a == 4
<class '__main__.d1'> 4 4