Re: Question about generators
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
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
>>> >>> 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
> 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
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
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
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
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
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
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
> 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/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
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.
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.
<[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