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


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

yield expression

Started byZiliang Chen <zlchen.ken@gmail.com>
First post2013-02-24 16:36 -0800
Last post2013-02-26 13:44 -0500
Articles 8 — 5 participants

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


Contents

  yield expression Ziliang Chen <zlchen.ken@gmail.com> - 2013-02-24 16:36 -0800
    Re: yield expression "Colin J. Williams" <cjw@ncf.ca> - 2013-02-26 11:34 -0500
      Re: yield expression Ian Kelly <ian.g.kelly@gmail.com> - 2013-02-26 09:50 -0700
      Re: yield expression Dave Angel <davea@davea.name> - 2013-02-26 12:05 -0500
      Re: yield expression "Vytas D." <vytasd2013@gmail.com> - 2013-02-26 17:07 +0000
        Re: yield expression "Colin J. Williams" <cjw@ncf.ca> - 2013-02-26 13:44 -0500
          Re: yield expression Dave Angel <davea@davea.name> - 2013-02-26 21:59 -0500
        Re: yield expression "Colin J. Williams" <cjw@ncf.ca> - 2013-02-26 13:44 -0500

#39831 — yield expression

FromZiliang Chen <zlchen.ken@gmail.com>
Date2013-02-24 16:36 -0800
Subjectyield expression
Message-ID<d7760f61-08dd-4186-8844-5f8415773a49@googlegroups.com>
Hi folks,
When I am trying to understand "yield" expression in Python2.6, I did the following coding. I have difficulty understanding why "val" will be "None" ? What's happening under the hood? It seems to me very time the counter resumes to execute, it will assign "count" to "val", so "val" should NOT be "None" all the time.

Thanks !

code snippet:
----
 def counter(start_at=0):
     count = start_at
     while True:
         val = (yield count)
         if val is not None:
             count = val
         else:
             print 'val is None'
             count += 1

[toc] | [next] | [standalone]


#39967

From"Colin J. Williams" <cjw@ncf.ca>
Date2013-02-26 11:34 -0500
Message-ID<kgio69$5i7$1@theodyn.ncf.ca>
In reply to#39831
On 24/02/2013 7:36 PM, Ziliang Chen wrote:
> Hi folks,
> When I am trying to understand "yield" expression in Python2.6, I did the following coding. I have difficulty understanding why "val" will be "None" ? What's happening under the hood? It seems to me very time the counter resumes to execute, it will assign "count" to "val", so "val" should NOT be "None" all the time.
>
> Thanks !
>
> code snippet:
> ----
>   def counter(start_at=0):
>       count = start_at
>       while True:
>           val = (yield count)
>           if val is not None:
>               count = val
>           else:
>               print 'val is None'
>               count += 1

Perhaps it's becaoue (teild count) is a statement.  Statements do not 
return a value.

Colin W.
>

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


#39969

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-02-26 09:50 -0700
Message-ID<mailman.2551.1361897462.2939.python-list@python.org>
In reply to#39967
On Tue, Feb 26, 2013 at 9:34 AM, Colin J. Williams <cjw@ncf.ca> wrote:
> Perhaps it's becaoue (teild count) is a statement.  Statements do not return
> a value.

yield is a bit of an odd duck in that it's both a statement and an
expression.  Compare:

http://docs.python.org/3/reference/simple_stmts.html#the-yield-statement

http://docs.python.org/3/reference/expressions.html#yieldexpr

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


#39973

FromDave Angel <davea@davea.name>
Date2013-02-26 12:05 -0500
Message-ID<mailman.2555.1361898338.2939.python-list@python.org>
In reply to#39967
On 02/26/2013 11:34 AM, Colin J. Williams wrote:
> On 24/02/2013 7:36 PM, Ziliang Chen wrote:
>> Hi folks,
>> When I am trying to understand "yield" expression in Python2.6, I did
>> the following coding. I have difficulty understanding why "val" will
>> be "None" ? What's happening under the hood? It seems to me very time
>> the counter resumes to execute, it will assign "count" to "val", so
>> "val" should NOT be "None" all the time.
>>
>> Thanks !
>>
>> code snippet:
>> ----
>>   def counter(start_at=0):
>>       count = start_at
>>       while True:
>>           val = (yield count)
>>           if val is not None:
>>               count = val
>>           else:
>>               print 'val is None'
>>               count += 1
>
> Perhaps it's becaoue (teild count) is a statement.  Statements do not
> return a value.
>
> Colin W.
>>
>

'yield count' is a yield_expression, not always a statement.  If it were 
the first thing in a statement, it'd be a yield_stmt


See the docs: http://docs.python.org/2/reference/simple_stmts.html

assignment_stmt ::=  (target_list "=")+ (expression_list | yield_expression)

and  http://docs.python.org/2/reference/expressions.html

yield_atom       ::=  "(" yield_expression ")"
yield_expression ::=  "yield" [expression_list]

The value produced by the yield expression is produced by   a.send() 
method.  This allows an approximation to coroutines.

I believe this dual usage of yield started in Python 2.5


-- 
DaveA

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


#39974

From"Vytas D." <vytasd2013@gmail.com>
Date2013-02-26 17:07 +0000
Message-ID<mailman.2556.1361898438.2939.python-list@python.org>
In reply to#39967

[Multipart message — attachments visible in raw view] — view raw

Hi,

You are using "yield" incorrectly. "yield" works like return, but it can
return more than once from the same function. Functions that "yield"
produce a so called "generator" object. This generator object gives you
values every time you call it.

The generator works very interesting way. It starts like normal function
and goes until it finds "yield" and returns the value. The state of
generator is saved - it is like it is put to sleep until you call it again.
So the next time you call generator() it runs from the point it returned
last time and will return you another value.

Simple sample of making and using generator (prints forever, so just kill
with CTRL+C).

def counter(start_at=0):
    """Returns integer each time called"""

    count = start_at
    while True:
        yield count
        count += 1

def main():
    generator = counter()

    while True:
        print(next(generator))


if __name__ == '__main__':
    main()


Hope helps.

Vytas D.



On Tue, Feb 26, 2013 at 4:34 PM, Colin J. Williams <cjw@ncf.ca> wrote:

> On 24/02/2013 7:36 PM, Ziliang Chen wrote:
>
>> Hi folks,
>> When I am trying to understand "yield" expression in Python2.6, I did the
>> following coding. I have difficulty understanding why "val" will be "None"
>> ? What's happening under the hood? It seems to me very time the counter
>> resumes to execute, it will assign "count" to "val", so "val" should NOT be
>> "None" all the time.
>>
>> Thanks !
>>
>> code snippet:
>> ----
>>   def counter(start_at=0):
>>       count = start_at
>>       while True:
>>           val = (yield count)
>>           if val is not None:
>>               count = val
>>           else:
>>               print 'val is None'
>>               count += 1
>>
>
> Perhaps it's becaoue (teild count) is a statement.  Statements do not
> return a value.
>
> Colin W.
>
>>
>>
> --
> http://mail.python.org/**mailman/listinfo/python-list<http://mail.python.org/mailman/listinfo/python-list>
>

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


#39986

From"Colin J. Williams" <cjw@ncf.ca>
Date2013-02-26 13:44 -0500
Message-ID<512D0276.5040909@ncf.ca>
In reply to#39974
On 26/02/2013 12:07 PM, Vytas D. wrote:
> Hi,
>
> You are using "yield" incorrectly. "yield" works like return, but it can
> return more than once from the same function. Functions that "yield"
> produce a so called "generator" object. This generator object gives you
> values every time you call it.
>
> The generator works very interesting way. It starts like normal function
> and goes until it finds "yield" and returns the value. The state of
> generator is saved - it is like it is put to sleep until you call it
> again. So the next time you call generator() it runs from the point it
> returned last time and will return you another value.
>
> Simple sample of making and using generator (prints forever, so just
> kill with CTRL+C).
>
> def counter(start_at=0):
>      """Returns integer each time called"""
>
>      count = start_at
>      while True:
>          yield count
>          count += 1
>
> def main():
>      generator = counter()
>
>      while True:
>          print(next(generator))
>
>
> if __name__ == '__main__':
>      main()
>
>
> Hope helps.
>
> Vytas D.
>
>
>
> On Tue, Feb 26, 2013 at 4:34 PM, Colin J. Williams <cjw@ncf.ca
> <mailto:cjw@ncf.ca>> wrote:
>
>     On 24/02/2013 7:36 PM, Ziliang Chen wrote:
>
>         Hi folks,
>         When I am trying to understand "yield" expression in Python2.6,
>         I did the following coding. I have difficulty understanding why
>         "val" will be "None" ? What's happening under the hood? It seems
>         to me very time the counter resumes to execute, it will assign
>         "count" to "val", so "val" should NOT be "None" all the time.
>
>         Thanks !
>
>         code snippet:
>         ----
>            def counter(start_at=0):
>                count = start_at
>                while True:
>                    val = (yield count)
>                    if val is not None:
>                        count = val
>                    else:
>                        print 'val is None'
>                        count += 1
>
>
>     Perhaps it's becaoue (teild count) is a statement.  Statements do
>     not return a value.
>
>     Colin W.
>
>
>
>     --
>     http://mail.python.org/__mailman/listinfo/python-list
>     <http://mail.python.org/mailman/listinfo/python-list>
>
>
Yes, it's very helpful.  Thanks also to the other two responders.

This brings us back to the OP question.  Why not " val = (yield count)"?

Colin W.

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


#40025

FromDave Angel <davea@davea.name>
Date2013-02-26 21:59 -0500
Message-ID<mailman.2590.1361933994.2939.python-list@python.org>
In reply to#39986
On 02/26/2013 01:44 PM, Colin J. Williams wrote:
> On 26/02/2013 12:07 PM, Vytas D. wrote:
>> Hi,
>>
>> You are using "yield" incorrectly. "yield" works like return, but it can
>> return more than once from the same function. Functions that "yield"
>> produce a so called "generator" object. This generator object gives you
>> values every time you call it.
>>
>> The generator works very interesting way. It starts like normal function
>> and goes until it finds "yield" and returns the value. The state of
>> generator is saved - it is like it is put to sleep until you call it
>> again. So the next time you call generator() it runs from the point it
>> returned last time and will return you another value.
>>
>> Simple sample of making and using generator (prints forever, so just
>> kill with CTRL+C).
>>
>> def counter(start_at=0):
>>      """Returns integer each time called"""
>>
>>      count = start_at
>>      while True:
>>          yield count
>>          count += 1
>>
>> def main():
>>      generator = counter()
>>
>>      while True:
>>          print(next(generator))
>>
>>
>> if __name__ == '__main__':
>>      main()
>>
>>
>> Hope helps.
>>
>> Vytas D.
>>
>>
>>
>> On Tue, Feb 26, 2013 at 4:34 PM, Colin J. Williams <cjw@ncf.ca
>> <mailto:cjw@ncf.ca>> wrote:
>>
>>     On 24/02/2013 7:36 PM, Ziliang Chen wrote:
>>
>>         Hi folks,
>>         When I am trying to understand "yield" expression in Python2.6,
>>         I did the following coding. I have difficulty understanding why
>>         "val" will be "None" ? What's happening under the hood? It seems
>>         to me very time the counter resumes to execute, it will assign
>>         "count" to "val", so "val" should NOT be "None" all the time.
>>
>>         Thanks !
>>
>>         code snippet:
>>         ----
>>            def counter(start_at=0):
>>                count = start_at
>>                while True:
>>                    val = (yield count)
>>                    if val is not None:
>>                        count = val
>>                    else:
>>                        print 'val is None'
>>                        count += 1
>>
>>
>>     Perhaps it's becaoue (teild count) is a statement.  Statements do
>>     not return a value.
>>
>>     Colin W.
>>
>>
>>
>>     --
>>     http://mail.python.org/__mailman/listinfo/python-list
>>     <http://mail.python.org/mailman/listinfo/python-list>
>>
>>
> Yes, it's very helpful.  Thanks also to the other two responders.
>
> This brings us back to the OP question.  Why not " val = (yield count)"?
>
> Colin W.
>
>

Repeating a misconception doesn't make it any more true.  yield is both 
an expression and a statement.  Nothing wrong with the statement
     val = (yield count)

although he apparently wasn't making any good use of the possible return 
value, since he observed it was always None.  That's just because he 
didn't use the send method in the calling function.

Most links I see on a web search explain only the expression form of 
yield, which is why i took a lot of time building the response I did 
earlier.


-- 
DaveA

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


#39988

From"Colin J. Williams" <cjw@ncf.ca>
Date2013-02-26 13:44 -0500
Message-ID<mailman.2564.1361904259.2939.python-list@python.org>
In reply to#39974
On 26/02/2013 12:07 PM, Vytas D. wrote:
> Hi,
>
> You are using "yield" incorrectly. "yield" works like return, but it can
> return more than once from the same function. Functions that "yield"
> produce a so called "generator" object. This generator object gives you
> values every time you call it.
>
> The generator works very interesting way. It starts like normal function
> and goes until it finds "yield" and returns the value. The state of
> generator is saved - it is like it is put to sleep until you call it
> again. So the next time you call generator() it runs from the point it
> returned last time and will return you another value.
>
> Simple sample of making and using generator (prints forever, so just
> kill with CTRL+C).
>
> def counter(start_at=0):
>      """Returns integer each time called"""
>
>      count = start_at
>      while True:
>          yield count
>          count += 1
>
> def main():
>      generator = counter()
>
>      while True:
>          print(next(generator))
>
>
> if __name__ == '__main__':
>      main()
>
>
> Hope helps.
>
> Vytas D.
>
>
>
> On Tue, Feb 26, 2013 at 4:34 PM, Colin J. Williams <cjw@ncf.ca
> <mailto:cjw@ncf.ca>> wrote:
>
>     On 24/02/2013 7:36 PM, Ziliang Chen wrote:
>
>         Hi folks,
>         When I am trying to understand "yield" expression in Python2.6,
>         I did the following coding. I have difficulty understanding why
>         "val" will be "None" ? What's happening under the hood? It seems
>         to me very time the counter resumes to execute, it will assign
>         "count" to "val", so "val" should NOT be "None" all the time.
>
>         Thanks !
>
>         code snippet:
>         ----
>            def counter(start_at=0):
>                count = start_at
>                while True:
>                    val = (yield count)
>                    if val is not None:
>                        count = val
>                    else:
>                        print 'val is None'
>                        count += 1
>
>
>     Perhaps it's becaoue (teild count) is a statement.  Statements do
>     not return a value.
>
>     Colin W.
>
>
>
>     --
>     http://mail.python.org/__mailman/listinfo/python-list
>     <http://mail.python.org/mailman/listinfo/python-list>
>
>
Yes, it's very helpful.  Thanks also to the other two responders.

This brings us back to the OP question.  Why not " val = (yield count)"?

Colin W.

[toc] | [prev] | [standalone]


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


csiph-web