Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #98847 > unrolled thread

Question about yield

Started byfl <rxjwg98@gmail.com>
First post2015-11-14 18:37 -0800
Last post2015-11-17 00:10 +1100
Articles 3 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  Question about yield fl <rxjwg98@gmail.com> - 2015-11-14 18:37 -0800
    Re: Question about yield Chris Angelico <rosuav@gmail.com> - 2015-11-15 13:43 +1100
    Re: Question about yield Steven D'Aprano <steve@pearwood.info> - 2015-11-17 00:10 +1100

#98847 — Question about yield

Fromfl <rxjwg98@gmail.com>
Date2015-11-14 18:37 -0800
SubjectQuestion about yield
Message-ID<ac359441-8cca-496c-b5c2-d3e7d7ce15dd@googlegroups.com>
Hi,
I have read a couple of tutorial on yield. The following code snippet still
gives me a shock. I am told yield is a little like return. I only see one 
yield in the tutorial examples. Here it has two yields. And there are three
variables following keyword yield.
I have not tried debug function to get the running states yet.
Could you give me some explanation on this yield usage?
Or are there some high relevant tutorial on this?

Thanks, 



def pfr(sequence, pos, stepsize, n):
  seq = iter(sequence)
  x = ones((n, 2), int) * pos                   # position
  f0 = seq.next()[tuple(pos)] * ones(n)         # model
  yield pos, x, ones(n)/n                       # weights
  for im in seq:
    x += uniform(-stepsize, stepsize, x.shape)  # 
    x  = x.clip(zeros(2), array(im.shape)-1).astype(int) # 
    f  = im[tuple(x.T)]                         # s
    w  = 1./(1. + (f0-f)**2)                    # distance
    w /= sum(w)                                 # w
    yield sum(x.T*w, axis=1), x, w              # weights
    if 1./sum(w**2) < n/2.:                     # degenerate:
      x  = x[res(w),:]                     # to weights

[toc] | [next] | [standalone]


#98848

FromChris Angelico <rosuav@gmail.com>
Date2015-11-15 13:43 +1100
Message-ID<mailman.345.1447555430.16136.python-list@python.org>
In reply to#98847
On Sun, Nov 15, 2015 at 1:37 PM, fl <rxjwg98@gmail.com> wrote:
> Or are there some high relevant tutorial on this?
>

Start here:

https://docs.python.org/3/tutorial/index.html

ChrisA

[toc] | [prev] | [next] | [standalone]


#98882

FromSteven D'Aprano <steve@pearwood.info>
Date2015-11-17 00:10 +1100
Message-ID<5649d5bf$0$1605$c3e8da3$5496439d@news.astraweb.com>
In reply to#98847
On Sun, 15 Nov 2015 01:37 pm, fl wrote:

> Hi,
> I have read a couple of tutorial on yield. The following code snippet
> still gives me a shock. I am told yield is a little like return. I only
> see one yield in the tutorial examples. Here it has two yields. And there
> are three variables following keyword yield.

Correct. `yield` exits the running function, but unlike `return`, the
function doesn't close down, it just pauses, ready to start up again when
you call next() on it.

Here is an example of an ordinary function:

py> def function():
...     return 1
...     return 2
...     return 3
...
py> function()
1
py> function()
1

Each time you call the function, it starts again at the beginning, and exits
after the first `return`. So the lines `return 2` and `return 3` are dead
code that never gets run.

Here is an example of a generator function with yield. Calling generators is
a bit different from calling a function: first you have to initialise them
by calling the function to create a "generator object", then you call the
next() function to advance to the next `yield` statement, and finally they
raise an exception when there are no more `yields`.

An example might help:

py> def generator():
...     yield 1
...     yield 2
...     yield 3
...
py> gen = generator()
py> next(gen)
1
py> next(gen)
2
py> next(gen)
3
py> next(gen)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration


To start the generator from the beginning again, you have to create a new
generator object by calling the function:

gen = generator()


Calling next() many times is often inconvenient. Normally you will iterate
over the generator:

for x in gen:
    print(x)

or you call collect all the items using list(). See example below.

Here is a generator which takes a list as argument, and returns a running
sum of the list values:

def running_sum(alist):
    total = 0
    for value in alist:
        total += value
        yield total


And here is an example of using it:

py> gen = running_sum(data)
py> list(gen)
[1, 3, 6, 16, 18, 18, 23]



-- 
Steven

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web