0

I am trying to sort a list by the class attribute of 'score' as the in built python sorted function seems to turn all other attributes of the object to "None". I have tried making a function to do this manually but when I run it the list inputted decreases in size as does the returned list, as well as the fact that the list becomes the same object repeated. The initial list is generated as follows:

para = []
class Parameters():
    att1 = random.randint(5,125)
    att2 = random.randint(5,125)
    att3 = random.randint(30,360)
    aa4 = random.randint(2,24)
    score = random.randint(0,100)

for i in range(0,19):
    para.append(Parameters())

Then my attempt at a sorting function is:

def sortPar(slist):
    sortlist = []
    sortlist = slist
    x = []
    val = 0
    minval = 1000000
    for item1 in slist: 
        minval = 10000000
        for item in sortlist:
            if item.score < minval:
                print(item.score)
                minval=item.score
                val=item
        x.append(val)
        sortlist.remove(val)
    return x 

What is going wrong within the code and is there any other way I can do this? Thanks for the help.

treutm
  • 5
  • 7
  • 5
    All those attributes are class attributes, shared by every instance. You don't want that. You need to make them instance attributes, so that each instance has its own collection of attributes. – PM 2Ring Aug 06 '18 at 12:52
  • See here https://www.pythoncentral.io/how-to-sort-a-list-tuple-or-object-with-sorted-in-python/, chapter "Sorting a List (or Tuple) of Custom Python Objects" – Humbalan Aug 06 '18 at 12:55
  • Sorry if this is a stupid question but how do I make them instance attributes? – treutm Aug 06 '18 at 12:55
  • you need a constructor – Humbalan Aug 06 '18 at 12:56
  • http://stackoverflow.com/questions/1680528/how-do-i-avoid-having-python-class-data-shared-among-instances – Daniel Roseman Aug 06 '18 at 12:57
  • Give the class an `__init__` method, and in that method do `self.att1 = random.randint(5,125)`, etc. – PM 2Ring Aug 06 '18 at 12:57
  • In other news, that's the least efficient possible sort algorithm – Daniel Roseman Aug 06 '18 at 12:58
  • Also give your class a `__repr__` method so you can print instances of the class and see what the values of its attributes are. – PM 2Ring Aug 06 '18 at 12:59
  • To define instance attributes you need to create a `def __init__(self):` method in your class. 2nd: when you do `sortlist.remove(val)` you also are modifying your `slist`. The way you copy your list is not the good way, you need to change your line `sortlist = slist` to either `sortlist = list(slist)` or `sorlist = slist[:]` or `sortlist = slist.copy()` Why ? Because what you wrote actually only copy the reference of the list (can be checked with `id()`) not the list itself, and thus modifying either will modify both. – Plopp Aug 06 '18 at 13:01
  • What Plopp said is correct, but you don't need to write your own sort function. The built-in `sort` can easily do what you want by giving it an appropriate `key` function argument, e.g.[`operator.attrgetter('score')`](https://docs.python.org/3/library/operator.html#operator.attrgetter). But you need to fix your class first. – PM 2Ring Aug 06 '18 at 13:06

1 Answers1

1

Sorting with sorted method:

import operator

para = []

class Parameters():

    def __init__(self):
        self.att1 = random.randint(5, 125)
        self.att2 = random.randint(5, 125)
        self.att3 = random.randint(30, 360)
        self.aa4 = random.randint(2, 24)
        self.score = random.randint(0, 100)


for i in range(0, 19):
    para.append(Parameters())

# using lambda
para_sorted = sorted(para, key=lambda x: x.score)
# using attrgetter
para_sorted2 = sorted(para, key=operator.attrgetter("score"))

If you want to write your own sorting algorithm would look at: https://www.tutorialspoint.com/python/python_sorting_algorithms.htm

Adelina
  • 10,915
  • 1
  • 38
  • 46
  • @PM2Ring I think lambda is a bit more easy to understand – Adelina Aug 06 '18 at 13:17
  • That tutorial site is a nice reference for those sorting algorithms, and it's good for coders to be familiar with them. But Python's Timsort is *very* good, so you should almost always use it for sorting 1D collections. – PM 2Ring Aug 06 '18 at 13:30