Re: Question about generators

2021-03-05 Thread Frank Millman

On 2021-03-06 8:21 AM, Frank Millman wrote:

Hi all

This is purely academic, but I would like to understand the following -

 >>>
 >>> a = [('x', 'y')]
 >>>
 >>> s = []
 >>> for b, c in a:
...   s.append((b, c))
...
 >>> s
[('x', 'y')]


This is what I expected.

 >>>
 >>> s = []
 >>> s.append(((b, c) for b, c in a))
 >>> s
[ at 0x019FC3F863C0>]
 >>>

I expected the same as the first one.

I understand the concept that a generator does not return a value until 
you call next() on it, but I have not grasped the essential difference 
between the above two constructions.





Thanks, Alan and Ming.

I think I have got it now.

In my first example, a 'for' loop both creates an iterable object *and* 
iterates over it.


In my second example, a generator expression creates an iterable object, 
but does nothing with it until asked.


Changing 'append' to 'extend' has the effect of iterating over the 
generator expression and appending the results.


Frank

--
https://mail.python.org/mailman/listinfo/python-list


Re: Question about generators

2021-03-05 Thread Ming
On Sat, Mar 06, 2021 at 08:21:47AM +0200, Frank Millman wrote:
> [...]
> I understand the concept that a generator does not return a value until you
> call next() on it, but I have not grasped the essential difference between
> the above two constructions.
> 
> TIA for any insights.
> 
> Frank Millman

In your first example, a certain element is appended to s each time in
the loop. But in your second example, the generator first traverses all
the elements, and then generates an iterable object, you are trying to
append this object to s.

Let's look at a simpler but more certain example:

a = [1, 2, 3]
s = []
for n in a:
s.append(n)
# Result: 
# len(s) == 3
# s == [1, 2, 3]

a = [1, 2, 3]
s = []
g = (n for n in a)
s.append(g)
# Result:
# len(s) == 1
# list(s[0]) == [1, 2, 3]

If you want to get the same result in the above two cases, just replace
append with extend.
list.extend() can accept an iterable object as input, and then append all
the elements to the original list.

-- 
OpenPGP fingerprint: 3C47 5977 4819 267E DD64  C7E4 6332 5675 A739 C74E


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Question about generators

2021-03-05 Thread Alan Bawden
   >>>
   >>> s = []
   >>> s.append(((b, c) for b, c in a))
   >>> s
   [ at 0x019FC3F863C0>]
   >>>

   TIA for any insights.

Replace "append" above with "extend" and observe the results.  Then
ponder the difference between append and extend.  I suspect that the
heart of your confusion actually has nothing to do with generators.

-- 
Alan Bawden
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Question about generators

2009-07-13 Thread Piet van Oostrum
> Cameron Pulsford  (CP) wrote:

>CP> I read it on the haskell site in their sieves/prime wheel section,
>CP> I guess I misunderstood something. (east to do over there...) I did
>CP> verify it against established list of primes and other generators
>CP> I've written that use more normal methods, but I only hand verified
>CP> it.

If it is used in a sieve then the non-primes will be sieved out.

>CP> It is at least interesting though, I can probably extend it to
>CP> check for primality by using a more normal sieve method. It might
>CP> be pretty fast too because generally it does only generate primes,
>CP> and the few non primes it does generate could be caught quickly
>CP> using a scratching out technique.

it does only generate primes => it does generate all primes.

>CP> When I was initially looking at it there are some interesting
>CP> patterns I might be able to extend into a generator that would
>CP> yield only correct sets of numbers for the 6x + n pattern.

As I wrote in my previous reply, in your use case the non-primes are
harmless. But it is useful to reflect that in the naming of your
identifiers. 

*And please, don't top post.*

-- 
Piet van Oostrum 
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: p...@vanoostrum.org
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question about generators

2009-07-12 Thread John Machin
On Jul 13, 1:17 pm, Cameron Pulsford 
wrote:
> I read it on the haskell site in their sieves/prime wheel section, I  
> guess I misunderstood something. (east to do over there...) I did  
> verify it against established list of primes and other generators I've  
> written that use more normal methods, but I only hand verified it.

"to verify" something means to ensure the truth or correctness, NOT
attempt to ensure ;-)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question about generators

2009-07-12 Thread Cameron Pulsford
I read it on the haskell site in their sieves/prime wheel section, I  
guess I misunderstood something. (east to do over there...) I did  
verify it against established list of primes and other generators I've  
written that use more normal methods, but I only hand verified it.


It is at least interesting though, I can probably extend it to check  
for primality by using a more normal sieve method. It might be pretty  
fast too because generally it does only generate primes, and the few  
non primes it does generate could be caught quickly using a scratching  
out technique.


When I was initially looking at it there are some interesting patterns  
I might be able to extend into a generator that would yield only  
correct sets of numbers for the 6x + n pattern.



On Jul 12, 2009, at 10:26 PM, John Machin wrote:


On Jul 13, 11:24 am, Cameron Pulsford 
wrote:


As far as the primes generator, it does not generate any non-primes.
All primes (except 2, 3 and 5) are in the form (6*x + 1, 6*x + 5)
where is x is [1, 2, ..., n]. The only time it doesn't generate a
prime is when x + (1 or 5) % 5 == 0. Which is what that last part is
making sure doesn't happen. I'm not a mathematician or anything so
correct me if I'm wrong, but that's what I've read.


Where did you read that? Have you tried to verify it, like this:

| >>> [6*i+j for i in range(1, 21) for j in (1, 5) if (i+j) % 5]
| [7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 49, 53, 59, 61, 67,
71, 73, 77, 79, 83, 89, 91, 97, 101, 103, 107, 109, 113, 119, 121]

49, 77, 91, and 121 are not prime.

--
http://mail.python.org/mailman/listinfo/python-list


--
http://mail.python.org/mailman/listinfo/python-list


Re: Question about generators

2009-07-12 Thread David Robinow
On Sun, Jul 12, 2009 at 9:24 PM, Cameron
Pulsford wrote:
> As far as the primes generator, it does not generate any non-primes. All
> primes (except 2, 3 and 5) are in the form (6*x + 1, 6*x + 5) where is x is
> [1, 2, ..., n]. The only time it doesn't generate a prime is when x + (1 or
> 5) % 5 == 0. Which is what that last part is making sure doesn't happen. I'm
> not a mathematician or anything so correct me if I'm wrong, but that's what
> I've read.
 All you're doing is eliminating numbers divisible by 2,3, and 5.
Your generator includes   49  (7 * 7),  77 (7*11), 91 (7*13), 121 (11*11),  etc.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question about generators

2009-07-12 Thread John Machin
On Jul 13, 11:24 am, Cameron Pulsford 
wrote:

> As far as the primes generator, it does not generate any non-primes.  
> All primes (except 2, 3 and 5) are in the form (6*x + 1, 6*x + 5)  
> where is x is [1, 2, ..., n]. The only time it doesn't generate a  
> prime is when x + (1 or 5) % 5 == 0. Which is what that last part is  
> making sure doesn't happen. I'm not a mathematician or anything so
> correct me if I'm wrong, but that's what I've read.

Where did you read that? Have you tried to verify it, like this:

| >>> [6*i+j for i in range(1, 21) for j in (1, 5) if (i+j) % 5]
| [7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 49, 53, 59, 61, 67,
71, 73, 77, 79, 83, 89, 91, 97, 101, 103, 107, 109, 113, 119, 121]

49, 77, 91, and 121 are not prime.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question about generators

2009-07-12 Thread Cameron Pulsford

itertools.chain() did it, thanks!

As far as the primes generator, it does not generate any non-primes.  
All primes (except 2, 3 and 5) are in the form (6*x + 1, 6*x + 5)  
where is x is [1, 2, ..., n]. The only time it doesn't generate a  
prime is when x + (1 or 5) % 5 == 0. Which is what that last part is  
making sure doesn't happen. I'm not a mathematician or anything so  
correct me if I'm wrong, but that's what I've read.


Also sorry if this was piggy backed, I started the thread as a fresh e- 
mail to python-list@python.org, sorry if I messed something up!


On Jul 12, 2009, at 8:15 PM, Terry Reedy wrote:


Cameron Pulsford wrote:

When you start a new thread, you should start a new thread and not  
piggyback on an existing thread.


--
http://mail.python.org/mailman/listinfo/python-list


--
http://mail.python.org/mailman/listinfo/python-list


Re: Question about generators

2009-07-12 Thread Terry Reedy

Cameron Pulsford wrote:

When you start a new thread, you should start a new thread and not 
piggyback on an existing thread.


--
http://mail.python.org/mailman/listinfo/python-list


Re: Question about generators

2009-07-12 Thread Piet van Oostrum
> Cameron Pulsford  (CP) wrote:

>CP> Hey everyone, I have this small piece of code that simply finds the
>CP> factors of a number.

Others have already given you advice to add the [2, 3, 5] to the
iterator (of which the primes.extend([2,3,5]) will not work). Please
allow me to make some other remarks.

>CP> import sys

>CP> def factor(n):
>CP> primes = (6*i+j for i in xrange(1, n) for j in [1, 5] if (i+j)%5 ! = 0)

It is a bit misleading to call this `primes' as it will also contain
non-primes. Of course they don't harm as they will never be considered a
factor because all their prime factors will have been successfully
removed before this non prime will be considered.

>CP> factors = []

>CP> for i in [2, 3, 5]:
>CP> while n % i == 0:
>CP> n /= i
>CP> factors.append(i)
>CP> for i in primes:
>CP> while n % i == 0:
>CP> n /= i
>CP> factors.append(i)

 You can stop the loop when n == 1. Like:
 if n == 1: break

>CP> print factors

>CP> factor(int(sys.argv[1]))

>CP> My question is, is it possible to combine those two loops? The primes
>CP> generator I wrote finds all primes up to n, except for 2, 3 and 5, so  I
>CP> must check those explicitly. Is there anyway to concatenate the hard  coded
>CP> list of [2,3,5] and the generator I wrote so that I don't need  two for
>CP> loops that do the same thing?

>CP> I tried writing a primes function using yield statements, but it  didn't
>CP> work like I thought it would.

See the recent thread `Why is my code faster with append() in a loop than with 
a large list?'
http://mail.python.org/pipermail/python-list/2009-July/718931.html
-- 
Piet van Oostrum 
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: p...@vanoostrum.org
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question about generators

2009-07-12 Thread Vilya Harvey
2009/7/12 Cameron Pulsford :
> My question is, is it possible to combine those two loops? The primes
> generator I wrote finds all primes up to n, except for 2, 3 and 5, so I must
> check those explicitly. Is there anyway to concatenate the hard coded list
> of [2,3,5] and the generator I wrote so that I don't need two for loops that
> do the same thing?

itertools.chain([2, 3, 5], primes) is what you're looking for, I think.

Vil.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question about generators

2009-07-12 Thread Mensanator
On Jul 12, 2:11 pm, Cameron Pulsford 
wrote:
> Hey everyone, I have this small piece of code that simply finds the  
> factors of a number.
>
> import sys
>
> def factor(n):
>      primes = (6*i+j for i in xrange(1, n) for j in [1, 5] if (i+j)%5 !
> = 0)
>
>      factors = []
>
>      for i in [2, 3, 5]:
>          while n % i == 0:
>              n /= i
>              factors.append(i)
>      for i in primes:
>          while n % i == 0:
>              n /= i
>              factors.append(i)
>      print factors
>
> factor(int(sys.argv[1]))
>
> My question is, is it possible to combine those two loops?

Yeah, get rid of the first loop.

> The primes  
> generator I wrote finds all primes up to n, except for 2, 3 and 5, so  
> I must check those explicitly. Is there anyway to concatenate the hard  
> coded list of [2,3,5] and the generator I wrote so that I don't need  
> two for loops that do the same thing?

primes.extend([2,3,5])

>
> I tried writing a primes function using yield statements, but it  
> didn't work like I thought it would.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question about generators.

2006-01-30 Thread kiwwisk
Thanks for reply :)
I'm little sceptic about this code:
>>> a = gen1()
>>> a.gi_frame.f_code.co_name
'gen1'

will it be compatible with Python 2.3, 2.4, 2.5+ and future versions?
Seems very internal and subject of future change.

A.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question about generators.

2006-01-30 Thread Paul McGuire
<[EMAIL PROTECTED]> wrote in message
news:[EMAIL PROTECTED]
> Hi,
> Is there a way for created generators to determine what function
> created them?
> Like for objects and classes function 'isinstance',
>
> e.g.:
>
> def gen1( ):
>yield 1
>
> a = gen1( )
>
> if isinstance( a, gen1 ) == True: #not functional.
>...
>
> Thanks for reply,
>Andrej
>

How's this? (Written using Python 2.4)
-- Paul

>>> def gen1():
... yield 1
...
>>> a = gen1()
>>> a.gi_frame.f_code.co_name
'gen1'
>>>


-- 
http://mail.python.org/mailman/listinfo/python-list