tags:

views:

84

answers:

2

Given a python class class Student(): and a list names = []; then I want to create several instances of Student() and add them into the list names,

names = [] # For storing the student instances
class Student():
    def __init__(self, score, gender):
        self.score = score
        self.gender = gender

And now I want to check out the scores of all the male students, can I do it like this?

scores = []
for i in names:
    if i.gender ==  "Male":
        scores.append(i.score)

My question is: How to create a list that can (if could be done by any statement) store the instance of Student? Or rather, when I write names = [], how could I state every element in names is an instance of Student so that I can use the attributs of this element despite python is weak type? I hope I made myself clear ;)

Can I write like:

    for i in range(len(names)):
        student = Student()
        student = names[i]
        if student.gender == "Male":
            # Whatever

I guess not...

+2  A: 

Did you try your code above? It should work fine. You can condense it into:

scores = [ student.name for student in names if student.gender == "Male" ]

Note that calling the list names is misleading, since it is a list of Student instances.

You can't define the list to be a list of Student instances; that's not how Python works.

Are you asking how to create the list that you've called names?

names = [ ]
for ( score, gender ) in <some-data-source>:
    names.append( Student( score, gender ) )

which is of course equivalent to

names = [ Student( score, gender ) for score, gender in <some-data-source> ]

and in turn to

names = [ Student( *row ) for row in <some-data-source> ]

If you need to do a lot of processing for each row then you can either move the processing into a separate function or use a for loop.

def process_row( row ):
    ...
    return score, gender

names = [ Student( *process_row( row ) ) for row in <some-data-source> ]

Responding to your edit, I think you are trying to declare the types of variables in Python. You wrote:

for i in range(len(names)):
    student = Student()
    student = names[i]
    if student.gender == "Male":
        # Whatever

What is the purpose of the line student = Student() -- are you trying to declare the type of the variable student? Don't do that. The following will do what you intended:

for student in students:
   if student.gender == "Male":
       # Whatever

Notice several things:

  1. We don't need to iterate over range(n) and then look up each instance in names; iterating over every element of a container is the purpose of a for loop.
  2. You don't need to make any claims about what student is -- it could be a string, a boolean, a list, a Student, whatever. This is dynamic typing. Likewise, students doesn't have to be a list; you can iterate over any iterable.
  3. When you write student.gender, Python will get the gender attribute of student, or raise an exception if it doesn't have one.
katrielalex
@katrielalex: thanks for the answer, I see your points, but I dont know how to express my problems, annoying though
ladyfafa
@katrielalex: the condensed look fairly neat and concise, in some cases, the if statement may invovle a bunch of TODOs, could this form works, might not be so straightforword??
ladyfafa
Huh? What's a `TODO`?
katrielalex
Well, means a lot of things to do :) i.e. if statement1, then do a lot of things
ladyfafa
@ladyfafa - put them in a separate function or instance method...
detly
+4  A: 

First of all python is not weakly typed. It is however dynamically typed so you can't specify an element type for your list.

However this does not prevent you from accessing an object's attributes. This works just fine:

names = [Student(1,"Male"), Student(2,"Female")]
scores = []
for i in names:
    if i.gender ==  "Male":
        scores.append(i.score)

It is however more pythonic to write this using a list comprehension:

names = [Student(1,"Male"), Student(2,"Female")]
scores = [i.score for i in names if i.gender == "Male"]
sepp2k
Actually, according to most definitions I think Python *is* weakly typed -- it supports overloading, implicit type conversions, polymorphism... If that isn't "weak typing", what is? Admittedly the term doesn't mean much anyway.
katrielalex
I'd also say has Python dynamic types. The OP knows only the opposite: *static* types. It seems that *strong* and *weak* are rather bad names for very similar concepts ..
THC4k
No. weak type means that there's no big difference within types. So you can add string variable to number as though it was a number too.In python you MUST aware of variable type. But it can be found runtime only or dynamically.
Odomontois
@Odomontois: Can you give an example of a language which is weakly typed by your definition?
katrielalex
@katrielalex Perl is common example.
Odomontois
@katrielalex, you might find this article enlightening: http://www.artima.com/weblogs/viewpost.jsp?thread=7590
Aaron Gallagher
@Aaron: thanks for the article. I'm not sure I see what it's trying to say; I think it's that Python is dynamically typed? @Odomontois: well, I'm no Perl expert but I'm fairly sure that even that most horrendous of language *distinguishes* between numbers and strings! It merely overloads a lot of common operations so that you don't need to worry about the difference. Notice that there are implicit type conversions in Python (`1+1.==2.`), though they are uncommon.
katrielalex
@katrielalex: Note that he said "no *big* difference". A language where there's no difference at all (i.e. there are no types) would be untyped, not just weakly typed. Bash script would be an example of an untyped language.
sepp2k
@katrielalex, in your example, both of the operands are numbers, though different types of numbers. Weakly-typed languages have implicit conversions between orthogonal types, e.g. strings and numbers.
Aaron Gallagher