The Yield statement

Mensanator mensanator at aol.com
Mon Jun 30 19:45:36 EDT 2008


On Jun 30, 5:31 pm, Alex Bryan <alexnbr... at gmail.com> wrote:
> Okay, so i don't really understand the Yield thing and i know it is  
> useful. I've read a few things about it but it is all programming  
> jargon and so basically it is hard for me to understand. So can anyone  
> give me a description or link me to a site that has a good definition  
> and/or examples of it? If you could I would really appreciate it.

You know what a function does, right? If I were to say

x = NextPrime(3)

then x should be set to 5. The NextPrime function
does this by evaluating the input argument (3) and
doing

return p

as the last statement (p having been determined to be 5).

Now, suppose you had a function Primes (i.e., a function
that returns ALL the primes). Obviously, since there are
an infinite number of them, the function would never
end since it would eventually eat up all your memory
trying to create a list with infinite elements.

However, if Primes were a generator, you could have it
return just 1 result at a time. The generator would
keep track of the last prime issued so that every .next()
call would give you the next prime in the sequence.

That's what "yield" does. It functions like a return,
only returning a single element of an iteration.
For infinite loops, the program simply stops calling
the function when it has enough (or tells the function
to stop).

Here's an example. Note that before it enters the output
loop it does a couple things. First, it checks for valid
input. If not valid, it executes a "return" statement
which kills the generator.

If valid, it issues a "yield" prior to the loop. It must
do this to issue the first partition. The loop will issue
all subsequent partitions with its "yield" statements.

This particular generator is always a finite loop. Although
the number of generated partitions can be quite large, best
to test by doing C(depth-1,width-1) before asking for
all the results (which is what "for i in p" does).

def partition_generator(depth,width):
  """creates all partions of a given depth,widtth (depth>=width)
  depth objects in width bins such that each bin has at least 1 object
  this function is a generator (does comb(depth-1,width-1) partitions)

  partition_generator(depth,width)
  depth:  total inverse rule 1 count (p of 2**p)
  width:  total inverse rule 2 count (q of 3**q)
  sv:     sequence vector (the partition)
  returns sequence vector [sv]
  """
  def move_col(c):
    sv[c-1] += 1
    sv[c] -= 1
  def find_c():
    i = -1
    while i<0:
      if sv[i]>1:
        return i
      i -= 1
  def rollover(c):
    move_col(c)
    sv[-1] = sv[c]
    sv[c] = 1
  if depth<width:                # error
    print 'depth',depth,'must be >= to width',width
    return                       # kills generator
  max_element = depth - width + 1
  sv = [1 for i in range(width)]
  sv[-1] = max_element
  yield sv[:]                    # first partition
  while sv[0]<max_element:       # rest are generated by this loop
    c = find_c()
    if c < -1:
      rollover(c)
      yield sv[:]   # must yield copy of sv, not sv
    else:
      move_col(c)
      yield sv[:]

p = partition_generator(6,4)

for i in p: print i

##  [1, 1, 1, 3]
##  [1, 1, 2, 2]
##  [1, 1, 3, 1]
##  [1, 2, 1, 2]
##  [1, 2, 2, 1]
##  [1, 3, 1, 1]
##  [2, 1, 1, 2]
##  [2, 1, 2, 1]
##  [2, 2, 1, 1]
##  [3, 1, 1, 1]



More information about the Python-list mailing list