简体   繁体   中英

Python Class is not working with sorted function

I am new to python and i was reading python documentation and in given example on http://docs.python.org/2/howto/sorting.html#key-functions i am stuck and i am not getting how it exactly working.

I am using eclipse Pydev to run this code ..

class Student:

    student_object = [
                  ('john', 'a', 15),
                  ('as', 'C', 12),
                  ('dave', 'B', 10)
                  ]

    def __init__(self, name, grade, age):
        self.name = name
        self.grade = grade
        self.age = age


    def __repr__(self):
        return repr((self.name, self.grade, self.age))



print sorted(Student.student_object, key=lambda Student: Student.age) 

ERROR

Traceback (most recent call last):
  File "C:\Users\user1\workspace\demPython\src\ru.py", line 26, in <module>
    print sorted(Student.student_object, key=lambda Student: Student.age) 
  File "C:\Users\user1\workspace\demPython\src\ru.py", line 26, in <lambda>
    print sorted(Student.student_object, key=lambda Student: Student.age) 
AttributeError: 'tuple' object has no attribute 'age'

How class and method works in python ?? Why this code is not working ??

EDIT

But i changein last line and replace with given line

print sorted(Student.student_object, key=lambda student: student[0])

it is working and giving me output [('as', 'C', 12), ('dave', 'B', 10), ('john', 'a', 15)]

It doesn't work because the items in student_object are not instances of your Student class, they are just normal tuples. That's why the error is 'tuple' object has no attribute 'age' .

You need to create the student objects first:

class Student(object):

    def __init__(self, name, grade, age):
        self.name = name
        self.grade = grade
        self.age = age

    def __repr__(self):
        return '{0.name} {0.grade} {0.age}'.format(self)

students = [Student('john','a',15), Student('as','C',12), Student('dave','B',10)]
print sorted(students, key=lambda x: x.age)

There is no field called age , in your student_object . So you need this

print sorted(Student.student_object, key=lambda Student: Student[2])

Alternatively, you can use itemgetter like this

from operator import itemgetter
getage = itemgetter(2)
print sorted(Student.student_object, key = getage)

Note: Don't name your variables with initial capital letters.

Your Student.student_object is just

student_object = [
              ('john', 'a', 15),
              ('as', 'C', 12),
              ('dave', 'B', 10)
              ]

and has nothing to do with the Student class, except that it is "inside" it. Something like

class Student:

    def __init__(self, name, grade, age):
        self.name = name
        self.grade = grade
        self.age = age


    def __repr__(self):
        return repr((self.name, self.grade, self.age))



student_object = [ Student('john', 'a', 15),
                   Student('as', 'C', 12),
                   Student('dave', 'B', 10) ]


print sorted(student_object, key=lambda x: x.age)

instead, would, since each element of the array is a Student instance, so the age attr is defined.

Classes define the structure and behavior of objects, aka instances. When you define a class, Student , like you do here, Python creates a function Student() , called an initializer, that you can use to create instances of that class. Since you provided an __init__ method for Student, Python will arrange to invoke that as the implementation of the initializer.

So, to create a Student object, you will need to invoke Student's initializer with the arguments specified by your __init__ method. For example: Student('john', 'A', 15) .

Your key function (ie the anonymous function you created with the lambda expression) expects to receive something with an age property. Presumably that's supposed to be an object which is an instance of the Student class. However:

  1. Naming a parameter as Student is simply incorrect. Student does not refer to the class here; it is just like any other function parameter, and simply gives a name to the argument you will be receiving in this function. Note that, unlike some languages, you don't have to mention both the type name and the variable name when you declare a parameter in Python; you just declare the variable name and start using it. Also note that it is very bad Python style to name variables starting with capital letters, for just this reason: it confuses people as to what are variables, what are classes, etc.
  2. The objects actually being passed to your key function are not Students. Since you invoke sorted() on a list of tuples, the items your function receives are tuples, which you can think of as instances of a built-in tuple type that Python provides.

So, first focus on getting a list of Students, and understanding exactly how creating objects works. Once you do that, calling sorted on it like you have done will work. Then, fix your key function to use a lowercase student parameter for sanity's sake, and you're good to go!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM