Определить новые элементы в списке [python] - PullRequest
0 голосов
/ 25 июня 2019

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


# 10 elements
some_list = ['hello', 'hi', 'bye', 'hello', 'okay']

Так что я использовал индекс списка и элемент списка вместе и хэшировал их, чтобы создавать уникальные хеши и сохранять их в Redis.

Поскольку это выполняется, пока True, мне нужно постоянно проверять наличие новых элементов в конце списка, он работает, когда список продолжает обновляться и расти, но при определенных условиях список сбрасывается так, чтоновый элемент добавляется к нему в конце, а начальный элемент удаляется (это допустимый случай).

Новый список выглядит следующим образом:

# 10 elements
some_list = ['hi', 'bye', 'hello', 'okay', 'new_element']

В таком случае,Так как индекс каждого элемента изменился, хэши различны, и он помещает каждый элемент в redis.

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

Пожалуйста, оставляйте комментарии, если представленная информация кажется неоднозначной или недостаточной.

Ответы [ 4 ]

0 голосов
/ 25 июня 2019

A list не представляется подходящим типом данных.Во-первых, очень большие списки станут неосуществимыми при сравнении всех элементов с другими, т. Е. Характеристики производительности очереди вашего рода являются квадратичными.Возможно, это не проблема для вас, и это не ответит на ваш вопрос.

Вы также можете посмотреть очередь , которая также не отвечает на ваш вопрос, но все же может быть полезной.

Также могут представлять интерес itertools .

Из вашего вопроса неясно, нужно ли вам помнить все когда-либо посещенные строки или только те изтекущий списокДля запоминания видимых строк рассмотрите возможность использования set, как уже предлагалось.

Мое последнее предложение: вместо удаления / отбрасывания элементов головы вы можете установить их на None или PLACEHOLDER = object(), вчтобы сохранить индексы.

Удачи.

0 голосов
/ 25 июня 2019

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

Может быть, вы могли бы использовать список временных меток, чтобы отслеживать, когда записи добавляются. Таким образом, каждой записи в вашем списке «redis» будет соответствующая запись в вашем списке «timestamp». Временная метка (или ее хэш) также может использоваться для идентификации в Redis. Все, что вам нужно убедиться, это то, что для каждой записи в списке «redis» соответствующая отметка времени добавляется в список «отметки времени». То же самое, когда вы удаляете первый элемент.

0 голосов
/ 25 июня 2019

Вы можете использовать следующий класс для достижения того, что вы хотите:

from typing import List, Iterator, Iterable, Union, overload, Optional, \
    Callable, Any


class UniqueError(ValueError):
    def __init__(self):
        super().__init__('all values in a UniqueList must be distinct')
        raise self


class UniqueList(list):
    def __init__(self, iterable=()) -> None:
        super().__init__(iterable)
        self.__unique = set(self)
        if len(self) != len(self.__unique):
            UniqueError()

    def clear(self) -> None:
        super().clear()
        self.__unique.clear()

    def copy(self) -> List[Any]:
        type_self = type(self)
        instance = type_self.__new__(type_self)
        super(type_self, instance).__init__(self)
        instance.__unique = self.__unique.copy()
        return instance

    def append(self, obj: Any) -> None:
        if obj in self.__unique:
            UniqueError()
        self.__unique.add(obj)
        super().append(obj)

    def extend(self, iterable: Iterable[Any]) -> None:
        copy = list(iterable)
        if any(obj in self.__unique for obj in copy):
            UniqueError()
        super().extend(copy)

    def pop(self, index: int = ...) -> Any:
        value = super().pop(index)
        self.__unique.remove(value)
        return value

    def index(self, obj: Any, start: int = ..., stop: int = ...) -> int:
        return super().index(obj, start, stop)

    def count(self, obj: Any) -> int:
        return int(obj in self.__unique)

    def insert(self, index: int, obj: Any) -> None:
        if obj in self.__unique:
            UniqueError()
        self.__unique.add(obj)
        super().insert(index, obj)

    def remove(self, obj: Any) -> None:
        super().remove(obj)
        self.__unique.remove(obj)

    def reverse(self) -> None:
        super().reverse()

    def sort(self, *, key: Optional[Callable[[Any], Any]] = ...,
             reverse: bool = ...) -> None:
        super().sort(key=key, reverse=reverse)

    def __len__(self) -> int:
        return super().__len__()

    def __iter__(self) -> Iterator[Any]:
        return super().__iter__()

    def __str__(self) -> str:
        return super().__str__()

    def __hash__(self) -> int:
        return super().__hash__()

    @overload
    def __getitem__(self, i: int) -> Any: ...

    @overload
    def __getitem__(self, s: slice) -> List[Any]: ...

    def __getitem__(self, i: int) -> Any:
        return super().__getitem__(i)

    @overload
    def __setitem__(self, i: int, o: Any) -> None: ...

    @overload
    def __setitem__(self, s: slice, o: Iterable[Any]) -> None: ...

    def __setitem__(self, i: int, o: Any) -> None:
        current = super().__getitem__(i)
        if current == o or o in self.__unique:
            UniqueError()
        self.__unique.add(o)
        self.__unique.remove(current)
        super().__setitem__(i, o)

    def __delitem__(self, i: Union[int, slice]) -> None:
        self.__unique.remove(super().__getitem__(i))
        super().__delitem__(i)

    def __add__(self, x: List[Any]) -> List[Any]:
        copy = self.copy()
        copy += x
        return copy

    def __iadd__(self, x: Iterable[Any]) -> List[Any]:
        self.extend(x)
        return self

    def __mul__(self, n: int) -> List[Any]:
        raise NotImplementedError('multiplication is not supported')

    def __rmul__(self, n: int) -> List[Any]:
        raise NotImplementedError('multiplication is not supported')

    def __imul__(self, n: int) -> List[Any]:
        raise NotImplementedError('multiplication is not supported')

    def __contains__(self, o: object) -> bool:
        return super().__contains__(o)

    def __reversed__(self) -> Iterator[Any]:
        return super().__reversed__()

    def __gt__(self, x: List[Any]) -> bool:
        return super().__gt__(x)

    def __ge__(self, x: List[Any]) -> bool:
        return super().__ge__(x)

    def __lt__(self, x: List[Any]) -> bool:
        return super().__lt__(x)

    def __le__(self, x: List[Any]) -> bool:
        return super().__le__(x)
0 голосов
/ 25 июня 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...