【问题标题】:Deleting an object from a list?从列表中删除对象?
【发布时间】:2020-04-17 20:10:24
【问题描述】:

所以我仍然是一个初学者程序员,我的任务是对 csv 文件创建的对象进行排序,这些对象具有属性 lname、fname、性别、年龄(按此顺序),并按 lname 属性对它们进行排序。我已经实现了这一点,但是我现在需要删除其中一个对象(我选择了一个随机的对象来测试),这就是我到目前为止所拥有的:

class FitClinic:
    def __init__(self, lname, fname, gender, age):
        self.lname = lname
        self.fname = fname
        self.gender = gender
        self.age = int(age)

    def __del__(self):
        print("Customer has been deleted")

    def get_lname(self):
        return self.lname

    def get_fname(self):
        return self.fname

    def get_gender(self):
        return self.gender

    def get_age(self):
        return self.age

fh=open('fit_clinic_20.csv', 'r')
fh.seek(3)
listofcustomers=[]
for row in fh:
    c = row.split(",")
    listofcustomers.append(FitClinic(c[0], c[1], c[2], c[3]))

sorted_list=sorted(listofcustomers,key=lambda x: x.get_lname())

for x in sorted_list:
    if x.get_lname()==("Appleton"):
        del x
    print(x.get_lname(),x.get_fname(),x.get_gender(),x.get_age())

现在它显然不起作用,我需要一些帮助。

【问题讨论】:

    标签: python csv sorting object del


    【解决方案1】:

    试试这个:

    for x in sorted_list:  # Loops through Customers in List
        if x.get_lname() == "Appleton":  # Check if the last name is Apple
            sorted_list.remove(x)  # Remove each from the list, Pretty self explanatory
        else:  # you only want to print if the last name is not APppleton
            print(x.get_lname(), x.get_fname(), x.get_gender(), x.get_age())
    

    .remove 从列表中删除一个对象,因此您不需要跟踪循环的索引。 阅读thisw3schools 教程了解更多列表操作

    【讨论】:

    • 在迭代列表时编辑列表是自找麻烦。
    【解决方案2】:

    此示例使用filter 效果更好,因为它会删除所有lnameAppleton 的诊所:

    sorted_list = list(filter(lambda c: c.get_lname() != "Appleton", sorted_list))
    

    如果您只想删除第一个,请使用Barmar's answer

    这与列表推导相同,Python 更擅长优化:

    sorted_list = [c for c in sorted_list if c.get_lname() != "Appleton"]
    

    【讨论】:

    • 如果你需要一个lambda 来使用filter,它会比不需要它的等价listcomp 慢; sorted_list = [c for c in sorted_list if c.get_lname() != "Appleton"] 更快、更简洁(如果你听 BDFL 的话,它也更“Pythonic”,他们通常讨厌 filter)。
    • @ShadowRanger 你是对的。 filter 可以更清楚,但这里的列表理解会更好。
    【解决方案3】:

    您可以使用列表推导从列表中删除项目:

    sorted_list[:] = [x for x in sorted_list if not(x.get_lname()==("Appleton"))]
    

    一个工作示例:

    class FitClinic:
        def __init__(self, lname):
            self.lname = lname
    
        def __del__(self):
            print("Customer has been deleted")
    
        def get_lname(self):
            return self.lname
    
    # Create example
    sorted_list = [FitClinic('a'), FitClinic('b'), FitClinic('c'), FitClinic('Appleton')]
    sorted_list[:] = [x for x in sorted_list if not(x.get_lname()=="Appleton")]
    

    现在 sorted_list 是。

    a
    b
    c
    

    【讨论】:

    • 我可以建议x.get_lname() != "Appleton"而不是not(x.get_lname()=="Appleton")吗?
    • @ShadowRanger 是的,如果你愿意,你可以使用它。
    【解决方案4】:

    del x只是删除临时变量x,对列表没有影响。您需要使用del listofcustomers[pos],但首先您必须在列表中找到位置。

    try:
        pos = next(i for i,v in enumerate(listofcustomers) if v.get_lname() == "Appleton")
        del listofcustomers[pos]
    except StopIteration:
        pass // Ignore if not found
    

    请参阅Python: return the index of the first element of a list which makes a passed function true,了解查找符合条件的元素索引的多种方法。

    【讨论】:

    • 由于您不使用来自pop 的返回,del listofcustomers[pos] 似乎是更直接(且速度稍快)的解决方案。 del 适用于按索引删除或删除属性,而不仅仅是原始顶级名称。
    • 可能没有太大区别,但看起来确实更简单。
    猜你喜欢
    • 2021-08-03
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 2019-01-25
    相关资源
    最近更新 更多