如果列表项不在另一个列表中,则删除列表项 - python

2023-12-10

这是我的情况。 我有一个 Person 对象的列表。

class Person():
    def __init__(self, name="", age=):
        self.name = name
        self.uid = str( uuid.uuid4( ) )
        self.age = age

我的 UI 包含一个显示这些项目的树视图。在某些情况下,如果用户愿意,他们可以拥有同一个人的实例。我突出显示那些粗体,让用户知道这是同一个人。

![enter image description here

问题 当用户删除树节点时,我需要知道是否应该从列表中删除实际对象。但是,如果正在使用该对象的另一个实例,那么我不应该删除它。

我对解决方案的想法。 在执行删除操作(仅删除树节点项目)之前,我将收集用户界面中使用的所有人员。

接下来我将继续删除树视图项目。

接下来获取 ui 中使用的另一个 objevst 集合。

最后比较两个列表并删除第二个列表中未出现的人员。

如果我采用这个解决方案,我最好做一个测试,比如

for p in reversed(original_list):
    if p not in new_list:
        original_list.remove(p)

或者我应该收集 uid 数字来进行比较而不是整个对象?

这些列表可能相当大。

Herr 是我第一次尝试处理删除操作的代码。当您关闭应用程序时,它会保存一个 json 文件。

https://gist.github.com/JokerMartini/4a78b3c5db1dff8b7ed8

这是我执行删除的功能。

def delete_treewidet_items(self, ctrl):
        global NODES
        root = self.treeWidget.invisibleRootItem()

        # delete treewidget items from gui
        for item in self.treeWidget.selectedItems():
            (item.parent() or root).removeChild(item)

        # collect all uids used in GUI
        uids_used = self.get_used_uids( root=self.treeWidget.invisibleRootItem() )

        for n in reversed(NODES):
            if n.uid not in uids_used:
                NODES.remove(n)

您还没有真正发布足够的代码,但据我所知:

import collections
import uuid

class Person():
    def __init__(self, name="", age=69):
        self.name = name
        self.uid = str( uuid.uuid4( ) )
        self.age = age

    def __eq__(self, other):
        return isinstance(other, Person) and self.uid == other.uid
    def __ne__(self, other): return self != other # you need this

    def __hash__(self):
        return hash(self.uid)

# UI --------------------------------------------------------------------------
persons_count = collections.defaultdict(int) # belongs to your UI class
your_list_of_persons = []  # should be a set

def add_to_ui(person):
    persons_count[person] += 1
    # add it to the UI

def remove_from_ui(person):
    persons_count[person] -= 1
    if not persons_count[person]: your_list_of_persons.remove(person)
    # remove from UI

所以基本上:

在执行删除操作(仅删除树节点项目)之前,我将收集用户界面中使用的所有人员。

否 - 您始终可以将此信息作为用户界面中的模块变量使用 -persons_count多于。这样您就不必复制列表。

仍然是创建人员的代码 - 然后是您的列表(其中包含distinct人所以应该是set)应该更新。如果这是在add_to_ui(有道理)你应该修改为:

def add_to_ui(name, age):
    p = Person(name, age)
    set_of_persons.add(p) # if already there won't be re-added and it's O(1)
    persons_count[person] += 1
    # add it to the UI

更进一步 - 你真的不需要你的原始列表 - 这只是persons_count.keys(),你只需修改:

def add_to_ui(name, age):
    p = Person(name, age)
    persons_count[person] += 1
    # add it to the UI

def remove_from_ui(person):
    persons_count[person] -= 1
    if not persons_count[person]: del persons_count[person]
    # remove from UI

这样你就明白了

EDIT:这是从我的最新迭代中删除的:

def delete_tree_nodes_clicked(self):
    root = self.treeWidget.invisibleRootItem()
    # delete treewidget items from gui
    for item in self.treeWidget.selectedItems():
        (item.parent() or root).removeChild(item)
        self.highlighted.discard(item)
        persons_count[item.person] -= 1
        if not persons_count[item.person]: del persons_count[item.person]

我已将我的解决方案(重写与第一个问题相关的代码)发布在:https://github.com/Utumno/so_34104763/commits/master。这是一个很好的重构练习 - 查看提交消息。我在这里特别介绍一下这个字典:https://github.com/Utumno/so_34104763/commit/074b7e659282a9896ea11bbef770464d07e865b7

可以做更多的工作,但我认为这是朝着正确方向迈出的一步 - 在大多数操作中也应该更快并节省内存

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果列表项不在另一个列表中,则删除列表项 - python 的相关文章

随机推荐