Welcome, guest | Sign In | My Account | Store | Cart
# Remove duplicates from a list:
>>> L = [1,2,2,3,3,3]
>>> [x for x in L if x not in locals()['_[1]'].__self__]
[1,2,3]


# That's a bit ugly, so let's encapsulate it in a function.
# Be carefull with nested list comprehensions. The inner one is
# called "_[2]" (or "_[3]", and so on if you nest them deeply).
def thislist():
    """Return a reference to the list object being constructed by the
    list comprehension from which this function is called. Raises an
    exception if called from anywhere else.
    """
    import sys
    d = sys._getframe(1).f_locals
    nestlevel = 1
    while '_[%d]' % nestlevel in d:
        nestlevel += 1
    return d['_[%d]' % (nestlevel - 1)].__self__

# More readable now:
>>> L = [1,2,2,3,3,3]
>>> [x for x in L if x not in thislist()]
[1,2,3]


# At any given point in the construction, the list is a fully functional
# list object. You can even call mutating methods on it.
# For example:

# Remove duplicates from a list, retaining only the *last* item from 
# each equivalency class:
>>> L = ['ab','a'+'b']
>>> map(id, L)
[16333632, 16332416]
>>> L2 = [x for x in L if x not in thislist() \
                        or not thislist().remove(x)]
>>> L2
['ab']
>>> map(id, L2) # make sure it worked...
[16332416]


# Another example: Finding prime numbers (Python 2.3+)
import itertools, sys, math

def primes_less_than(N):
    return [p for p in itertools.chain([2],xrange(3,N,2))
            if 0 not in itertools.imap(lambda x:p%x,
                                       itertools.takewhile(
                                           lambda v:v <= math.sqrt(p),
                                           thislist() ))]

def first_N_primes(N):
    return [p for p in itertools.takewhile(lambda _,L=thislist():len(L) < N,
                                           itertools.chain([2],xrange(3,sys.maxint,2)))
            if 0 not in itertools.imap(lambda x:p%x,
                                       itertools.takewhile(
                                           lambda v:v <= math.sqrt(p),
                                           thislist()))]

# For lazy typists:
plt = primes_less_than
fnp = first_N_primes

>>> plt(20)
[2, 3, 5, 7, 11, 13, 17, 19]
>>> fnp(10)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

History

  • revision 3 (20 years ago)
  • previous revisions are not available