识别列表[python]

时间:2019-06-25 13:28:47

标签: python python-3.x list hash

我有一个不断更新的列表,其中包含重复的元素,例如


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

所以我将列表索引和列表元素一起使用并对其进行哈希处理,以创建唯一的哈希并将其存储在Redis上。

由于这是在True期间运行的,因此我需要在列表末尾不断检查新元素,当列表不断更新和增长时,它就可以工作, 但是在特定条件下,列表会重置,以便在末尾添加一个新元素,然后删除起始元素(这是有效的情况)。

新列表如下:

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

在这种情况下,由于每个元素的索引都发生了变化,因此哈希值有所不同,因此会将每个元素放入redis。

任何能帮助我识别如何在添加新元素的同时识别旧元素的解决方案,将受到高度赞赏。

如果所提供的信息含糊不清或不足,请发表评论。

4 个答案:

答案 0 :(得分:0)

如果可能的话,您可以改用有序词典来解决问题。然后,您可以将这些键用作簿记参数来检查新元素。

答案 1 :(得分:0)

虽然我认为另一个答案是最优雅,最正确的方法,但这是一种变通方法,以防更改软件体系结构不可行。

也许您可以使用时间戳列表来跟踪添加条目的时间。 因此,对于“ redis”列表中的每个条目,“ timestamp”列表中都会有一个对应的条目。时间戳(或其哈希)也可以用作Redis的标识。您需要确保的是,对于“ redis”列表中的每个条目,都会在“ timestamp”列表中添加一个相应的时间戳。删除第一个元素时相同。

答案 2 :(得分:0)

您也许可以使用下面的类来完成您想要做的事情:

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)

答案 3 :(得分:0)

list似乎不是适当的数据类型。首先,在将所有元素与另一个元素进行比较时,非常大的列表将变得不可行,即排序队列的性能特征是二次方的。这可能对您来说不是问题,也不能回答您的问题。

您可能还想看看queue,它也不能回答您的问题,但可能仍会有所帮助。

另外,itertools可能很有趣。

从您的问题尚不清楚,您是否需要记住所有曾经访问过的字符串,还是仅记住当前列表中的那些字符串。如前所述,要记住字符串,请考虑使用set

我最后的建议是:为了保留索引,您可能不想将head元素设置为NonePLACEHOLDER = object(),而不是将它们放置在顶部。

祝你好运。