tags:

views:

152

answers:

3

In Perl, one can do the following

for (@foo) {
    # do something 
    next if $seen{$_}++;
}

I would like to be able to do the equivalent in Python, that is to skip a block if it has been executed once.

+11  A: 
seen = set()
for x in foo:
    if x in seen:
        continue
    seen.add(x)
    # do something

See the set documentation for more information.

Also, the examples at the bottom of the itertools module documentation contains a unique_everseen generator that you can use like this:

for x in unique_everseen(foo):
    # do something
Greg Hewgill
Thanks. Looks like unique_everseen might fit the bill although it seems to be listed as an optional recipe instead of being part of the module.
jnman
jnman, don't let anyone force Python on you. I mean, from the way you choose to write your comments, it's obvious that you find Python at best a necessary evil (perhaps it's a job requirement) and its library severely lacking (contrary to, say, the magnificent CPAN).
ΤΖΩΤΖΙΟΥ
I am much more comfortable using perl than python. However, due to some stuff that I am currently working on, I have to use python instead hence the questions. It just seems that this particular perl(ism) is sufficiently useful (to me) that I am somewhat surprised that there is no equivalent "terse" version in python (to use your words).
jnman
@jnman - Python and terse usually don't go together. If you want terse, stick with Perl. I bet money CPAN has a package to do whatever "stuff you're currently working on" that you're using Python for. (I like (and dislike) both languages, but I am a bit biased towards Perl since it's my native tongue, so to speak.)
Chris Lutz
+2  A: 
seen={}
for item in foo:
   if seen.has_key(item):
      seen[item]+=1
      continue # continue is optional, just to illustrate the "next" in Perl
   else:
      seen[item]=1
ghostdog74
Alternatively `from collections import defaultdict; seen = defaultdict(int); for item in foo: seen[item] += 1; if seen[item] > 1: continue; #rest of code` (with proper indentation, of course.)
Chris Lutz
yes, +1 for that. But I guess i am still old school, so this works for version <2.4+
ghostdog74
+1  A: 

If you don't care about the order of the things in foo, and only that the unique items are iterated over, then the solution is much simpler.

for x in set(foo):
    do something
Paul Hankin