[Tutor] Help understanding list comprehensions

Laura Creighton lac at openend.se
Wed Jun 17 13:28:38 CEST 2015


In a message of Wed, 17 Jun 2015 14:28:54 +0530, Anubhav Yadav writes:
>Either the subject is misleading or you misunderstand something. Im am
>sorry to tell you the great truth, but there was no list comprehension  in
>your code at all, just a list. Comprehension is what Alan wrote for you,
>that is the next step in studying Python, when you already understand lists
>and loops well.
>
>
>I understand that my title was a little misleading, and I apologise for the
>same. Here is code that worked:
>
>marks = []
>for i in range(int(input())):
>    name = raw_input()
>    score = float(raw_input())
>    marks.append([name, score])
>marks = sorted(marks, key=lambda score:score[1])
>lowest = marks[0][1]
>marks = [ x for x in marks if x[1] != lowest]
>second_lowest = marks[0][1]
>lowest = sorted([x for x in marks if x[1]==second_lowest])
>for row in lowest:
>    print row[0]

>And it worked because I was using list comprehensions for removing the
>element from the list. It didn't worked in the for loop before. I wanted to
>ask why it didn't worked in for loop but worked in list comprehension.

You have this problem.
Type "help", "copyright", "credits" or "license" for more information.
>>> mylist = [1,2,3]
>>> for i in mylist:
...     print i
...     mylist.remove(i)
...
1
3
>>> mylist
[2]

--------
you didn't want to skip over 2.

--------
So do this instead.

>>> from copy import copy
>>> mylist=[1,2,3]
>>> mylist_copy=copy(mylist)
>>> for i in mylist_copy:
...     print i
...     mylist.remove(i)
...
1
2
3
>>> mylist
[]
>>> mylist_copy
[1, 2, 3]

------------

Much better. :)  This goes to show that you shouldn't delete items out
of a list you are interating over, unless you want the weird output
you got above.  But even if you did -- it will confuse the heck out
of the next person to read your code, which may be you in six months
time, so even then it might be better to rewrite the thing.

Make a copy of the list instead.  Now, python gives you lots of ways to
make copies.  One way is to use the copy command, as I did.  This has
the advantage that everybody knows exactly what it is that you did.
It has the disadvantage that people have to type 'from copy import copy'
and some people -- I am not one of them -- find it too much typing.

So they write it as:
>>> mylist=[1,2,3]
>>> mylist_copy=mylist[:]
>>> mylist
[1, 2, 3]
>>> mylist_copy
[1, 2, 3]

and since this way of doing things is so very well known, you mostly don't
confuse people by copying that way.

And, as you may have found out in code not here, you can use a
list comprehension to construct a whole new list, so again you
wouldn't have the problem of deleting items out of a list you
are iterating over, because it is a different list.

But you are mistaken when you write:

>And it worked because I was using list comprehensions for removing the
>element from the list. It didn't worked in the for loop before. I wanted to
>ask why it didn't worked in for loop but worked in list comprehension.

(at least with respect to that code).  In the code you posted you didn't
remove anything from the list at all.

Laura


More information about the Tutor mailing list