2

So I am still a beginner programmer who has been tasked with sorting objects created by a csv file with the attributes lname, fname, gender, age (in that order) and sort them by the lname attribute. I have achieved this, however I now need to delete one of the objects (I chose a random one to test) and this is what I have so far:

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())

now it obviously doesnt work and I need some help.

osmans
  • 35
  • 3

4 Answers4

4

del x just deletes the temporary variable x, it has no effect on the list. You need to use del listofcustomers[pos], but first you have to find the position in the list.

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

See Python: return the index of the first element of a list which makes a passed function true for numerous ways to find the index of an element that matches a criteria.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Since you don't use the return from `pop`, `del listofcustomers[pos]` seems the more direct (and slightly faster) solution. `del` works for deleting by index or deleting attributes, not just raw top level names. – ShadowRanger Dec 28 '19 at 03:36
  • Probably doesn't make too much difference but that does seem more straightforward. – Barmar Dec 28 '19 at 03:39
1

This example is better with filter since it removes all clinics where lname is Appleton:

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

If you want to remove only the first one, use Barmar's answer.

This is the same as a list comprehension, which Python is better at optimizing:

sorted_list = [c for c in sorted_list if c.get_lname() != "Appleton"]
Anonymous
  • 11,748
  • 6
  • 35
  • 57
  • 1
    If you need a `lambda` to use `filter`, it's going to be slower than an equivalent listcomp that doesn't need it; `sorted_list = [c for c in sorted_list if c.get_lname() != "Appleton"]` is both faster and more concise (as well as more "Pythonic" if you listen to the BDFL, who hates `filter` in general). – ShadowRanger Dec 28 '19 at 03:38
  • @ShadowRanger You're right. `filter` can be clearer, but a list comprehension would be better here. – Anonymous Dec 28 '19 at 03:42
1

You can remove an item from a list with list comprehension:

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

A working example:

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")]

Now sorted_list is.

a
b
c
Leonardo Mariga
  • 1,166
  • 9
  • 17
0

Just Try this:

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 removes an object from a list so you do not need to track the index of the loop. Read this w3schools tutorial for more list operations