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


Question about generators

2021-03-05 Thread Frank Millman

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.


TIA for any insights.

Frank Millman

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


Re: Question about generators

2009-07-13 Thread Piet van Oostrum
 Cameron Pulsford cameron.pulsf...@gmail.com (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 p...@cs.uu.nl
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: p...@vanoostrum.org
-- 
http://mail.python.org/mailman/listinfo/python-list


Question about generators

2009-07-12 Thread Cameron Pulsford
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? 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?


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

2009-07-12 Thread Mensanator
On Jul 12, 2:11 pm, Cameron Pulsford cameron.pulsf...@gmail.com
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

2009-07-12 Thread Vilya Harvey
2009/7/12 Cameron Pulsford cameron.pulsf...@gmail.com:
 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 Piet van Oostrum
 Cameron Pulsford cameron.pulsf...@gmail.com (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 p...@cs.uu.nl
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 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 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 John Machin
On Jul 13, 11:24 am, Cameron Pulsford cameron.pulsf...@gmail.com
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 David Robinow
On Sun, Jul 12, 2009 at 9:24 PM, Cameron
Pulsfordcameron.pulsf...@gmail.com 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 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 cameron.pulsf...@gmail.com
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 John Machin
On Jul 13, 1:17 pm, Cameron Pulsford cameron.pulsf...@gmail.com
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


Question about generators.

2006-01-30 Thread kiwwisk
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

-- 
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


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