Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Lists - returning all occurences of value
Index -> Programming, Python -> Python Help
Goto page 1, 2  Next
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
mike200015




PostPosted: Thu Jan 24, 2008 10:19 am   Post subject: Lists - returning all occurences of value

Is there a way to return the position of all occurrences of a certain value in a list. I know there is a built in list function index() which returns the position of the first occurrence of a given value, but I need to know the position of all occurrences.
Sponsor
Sponsor
Sponsor
sponsor
Nick




PostPosted: Thu Jan 24, 2008 11:14 am   Post subject: RE:Lists - returning all occurences of value

well couldn't you just print your list to see all values?
wtd




PostPosted: Thu Jan 24, 2008 12:44 pm   Post subject: RE:Lists - returning all occurences of value

As far as I know there is no built-in method to do this, but it's all of two concise lines of code to define it yourself.

code:
def all_indexes(lst, f):
    return (i for i, x in enumerate(lst) if f(x))

a = [1, 2, 3, 4, 3, 2, 1]

print list(all_indexes(a, lambda x: x == 1))


Outputs:

code:
[0, 6]
mike200015




PostPosted: Thu Jan 24, 2008 1:07 pm   Post subject: Re: Lists - returning all occurences of value

yea that would work great! thanks wtd Smile
wtd




PostPosted: Thu Jan 24, 2008 2:42 pm   Post subject: RE:Lists - returning all occurences of value

It's worth asking... do you understand how the code I posted works?
mike200015




PostPosted: Thu Jan 24, 2008 3:10 pm   Post subject: Re: Lists - returning all occurences of value

yea i do after looking over it for a few mins... the only confusing part that i'm not 100% on is the return statement.. looks confusing since its on a single line. I understand what is being returned, just not clear on how it works as a single line
wtd




PostPosted: Thu Jan 24, 2008 4:05 pm   Post subject: RE:Lists - returning all occurences of value

The function is returning a generator object, which is created by the generator expression:

code:
i for i, x in enumerate(lst) if f(x)


Understanding how this works is the key to understanding the magic of this function.

Note that the enumerate function also returns a generator object.

In earlier version of Python we had list comprehensions, and they were good.

Let's say you have a list:

code:
my_list = [1, 4, 3, 2]


You can transform that into another list like so:

code:
my_other_list = [x * 2 for x in my_list]


At which point you'd have:

code:
[2, 8, 6, 4]


And you can tack on conditionals.

code:
my_other_list = [x * 2 for x in my_list if x * 2 <= 6]


From which you get:

code:
[2, 6, 4]


Now, what's the problem with list comprehensions? Well, let's say I have a list "my_list" with one million values in it. That's a big list, and it takes a lot of memory.

Now, let's say I want to iterate over a transformation of that list.

code:
for x in [(x * 2 - 1) / 3 for x in my_list]:
    print x


The list comprehension generates the entire new list before it even begins iterating. Now I have two huge lists in memory, and a lot of computation going on before I even begin to do anything useful with that data.

What if I leave the loop early?

code:
for x in [(x * 2 - 1) / 3 for x in my_list]:
    print x
    if x == 42:
        break


That might break after the first run of the loop. That means I've done a whole lot of computation, and used a whole lot of memory for nothing.

This is not ideal.

Generator objects and expressions fix this by introducing a sort of laziness. Rather than generating an entirely new list in its entirety, we simply have an object that when a certain method is called, will give the program its next value. If we only ask it for one value, then it only does that much work.

Does this make sense? Don't worry if it doesn't at first. Python is an enormously powerful programming language, and it can break even strong minds.
mike200015




PostPosted: Thu Jan 24, 2008 4:24 pm   Post subject: Re: Lists - returning all occurences of value

That makes sense, but the list comprehension looks the same as the generator object/expression. What would the list comprehension example you showed look like as a generator object/expression ?
Sponsor
Sponsor
Sponsor
sponsor
wtd




PostPosted: Thu Jan 24, 2008 4:29 pm   Post subject: RE:Lists - returning all occurences of value

It'd look like:

code:
for x in ((x * 2 - 1) / 3 for x in my_list):
    print x
    if x == 42:
        break
mike200015




PostPosted: Thu Jan 24, 2008 4:36 pm   Post subject: Re: Lists - returning all occurences of value

hmm.. Confused a little confused lol
wtd




PostPosted: Thu Jan 24, 2008 5:26 pm   Post subject: RE:Lists - returning all occurences of value

Note that the square brackets got replaced with parentheses. The syntactic similarity was intentional on the part of the language designers.
mike200015




PostPosted: Fri Jan 25, 2008 1:58 pm   Post subject: Re: Lists - returning all occurences of value

Idea I didnt notice that. So thats the difference between making a list comprehension and a generator expression?
McKenzie




PostPosted: Fri Jan 25, 2008 8:20 pm   Post subject: Re: Lists - returning all occurences of value

The most important thing is that you understand your own code. If you find what wtd posted to be a little to dense try a more imperative approach like:
Python:
def findAll(lst, val):
    ans = []
    for i in range(len(lst)):
        if lst[i] == val:
            ans.append(i)
    return ans

nums = [1,2,3,4,1,5,1,6,1,7]
print findAll(nums,1)
wtd




PostPosted: Sat Jan 26, 2008 1:20 am   Post subject: Re: Lists - returning all occurences of value

Just for fun, let's slowly morph that:

code:
def findAll(lst, val):
    ans = []
    for i in range(len(lst)):
        if lst[i] == val:
            ans.append(i)
    return ans


Becomes:

code:
def findAll(lst, val):
    ans = [i for i in range(len(lst)) if lst[i] == val]
    return ans


Becomes:

code:
def findAll(lst, val):
    return [i for i in range(len(lst)) if lst[i] == val]


Now, consider:

code:
>>> lst = [3, 5, 2]
>>> for i in range(len(lst)):
...     print i, lst[i]
...
0 3
1 5
2 2
>>> for i, x in enumerate(lst):
...     print i, x
...
0 3
1 5
2 2
>>>


So, we can now...

code:
def findAll(lst, val):
    return [i for i, x in enumerate(lst) if x == val]
shaon




PostPosted: Thu Jan 31, 2008 7:49 pm   Post subject: Re: Lists - returning all occurences of value

how come you used enumerate over for i in range(....), is enumerate more efficient or is just for less typing?
Display posts from previous:   
   Index -> Programming, Python -> Python Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 2  [ 16 Posts ]
Goto page 1, 2  Next
Jump to:   


Style:  
Search: