Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #81367 > unrolled thread
| Started by | "Ivan Evstegneev" <webmailgroups@gmail.com> |
|---|---|
| First post | 2014-11-23 16:56 +0200 |
| Last post | 2014-11-23 17:46 +0000 |
| Articles | 17 — 9 participants |
Back to article view | Back to comp.lang.python
Comprehension with two variables - explanation needed "Ivan Evstegneev" <webmailgroups@gmail.com> - 2014-11-23 16:56 +0200
Re: Comprehension with two variables - explanation needed Rustom Mody <rustompmody@gmail.com> - 2014-11-23 07:09 -0800
RE: Comprehension with two variables - explanation needed "Ivan Evstegneev" <webmailgroups@gmail.com> - 2014-11-23 17:37 +0200
Re: Comprehension with two variables - explanation needed Chris Angelico <rosuav@gmail.com> - 2014-11-24 02:42 +1100
RE: Comprehension with two variables - explanation needed Skip Montanaro <skip.montanaro@gmail.com> - 2014-11-23 09:45 -0600
Re: Comprehension with two variables - explanation needed Roy Smith <roy@panix.com> - 2014-11-23 10:57 -0500
Re: Comprehension with two variables - explanation needed Rustom Mody <rustompmody@gmail.com> - 2014-11-23 08:45 -0800
Re: Comprehension with two variables - explanation needed Rustom Mody <rustompmody@gmail.com> - 2014-11-23 09:17 -0800
RE: Comprehension with two variables - explanation needed "Ivan Evstegneev" <webmailgroups@gmail.com> - 2014-11-23 19:27 +0200
Re: Comprehension with two variables - explanation needed Steven D'Aprano <steve@pearwood.info> - 2014-11-24 04:42 +0000
Re: Comprehension with two variables - explanation needed Chris Angelico <rosuav@gmail.com> - 2014-11-24 15:51 +1100
Re: Comprehension with two variables - explanation needed Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-11-25 09:20 +1100
Re: Comprehension with two variables - explanation needed Rustom Mody <rustompmody@gmail.com> - 2014-11-23 22:47 -0800
Re: Comprehension with two variables - explanation needed Dan Stromberg <drsalists@gmail.com> - 2014-11-24 16:42 -0800
Re: Comprehension with two variables - explanation needed Skip Montanaro <skip.montanaro@gmail.com> - 2014-11-23 10:45 -0600
Re: Comprehension with two variables - explanation needed Roy Smith <roy@panix.com> - 2014-11-23 12:08 -0500
Re: Comprehension with two variables - explanation needed Jon Ribbens <jon+usenet@unequivocal.co.uk> - 2014-11-23 17:46 +0000
| From | "Ivan Evstegneev" <webmailgroups@gmail.com> |
|---|---|
| Date | 2014-11-23 16:56 +0200 |
| Subject | Comprehension with two variables - explanation needed |
| Message-ID | <mailman.16184.1416754678.18130.python-list@python.org> |
[Multipart message — attachments visible in raw view] — view raw
Hello guys, I would like to ask you for some explanations on comprehensions. (Don't be scared, it just some particular example ^_^) I found this little "find prime number" example over the internet: >>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)] >>> primes = [x for x in range(2, 50) if x not in noprimes] >>> print primes [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47] It looked pretty clear to me, till the time I decided to make some changes to it %))) Ok this is the case: As you can see the first line's comprehension produces a list, that includes all the multiplications of "i" (that range(2,8) ) in range (i*2, 50, i). So I get this pattern: noprimes = = [4, 6, 8...48, 6, 9,12.. ]. The change that I tried to apply to this comprehension would lead to the following pattern: noprimes = = [[4, 6,8.48], [6, 9, 12..], ..,[some numbers]] But despite my struggling on it for the whole day, I haven't got to the desirable result(using comprehensions only) Please, don't get me wrong, I'm not a lazy one (just a beginner). In my case, I made some googling, and found some patterns for matrices, that look this one(for example): Matrix = [[0 for x in range(5)] for x in range(5)] But when I tried to use square brackets with my code, it yields an error about definition of "i", for instance: File "<pyshell#30>", line 1, in <module> noprimes = [[j for i in range(2, 8)] for j in range(i*2, 50, i)] NameError: name 'i' is not defined. Then I tried to apply those brackets to "j", like this: >>> noprimes = [[j] for i in range(2, 8) for j in range(i*2, 50, i)] In this case I get, pretty predictable result, like this: [[num], [num], [num],...,[num]], and this is still not what I'm looking for.. So I moved further, and succeeded to solve my problem in a different manner: >>> noprimes=[] >>> for i in range(2,8): noprimes.append(list(range(i*2,50,i))) Which yields, in fact, the matrix I wanted from the beginning: noprimes == [[4, 6, 8, 10, 12,.., 48], [6, 9, 12, 15, 18, ., 42, 45, 48],..,[numbers]] Yep, this the "classical" way for me, on the other hand I have the feeling, that this is not, the ultimate solution. ^_^ So my questions is still persists: 1) Is it possible to realize such a thing by applying changes only to initial comprehension? If yes, it would be nice to see the solution. 2) How actually bad is my solution? I mean, after all, there are nested functions call in my code, so how much the speed is affected(if any)? Thanks a lot in advance, Ivan.
[toc] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2014-11-23 07:09 -0800 |
| Message-ID | <d1194d28-e9ed-4bd3-86e9-899e13a17097@googlegroups.com> |
| In reply to | #81367 |
On Sunday, November 23, 2014 8:28:16 PM UTC+5:30, Ivan Evstegneev wrote: > Hello guys, > > I would like to ask you for some explanations on comprehensions. (Don't be scared, it just some particular example ^_^) > > I found this little "find prime number" example over the internet: > > >>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)] > >>> primes = [x for x in range(2, 50) if x not in noprimes] > >>> print primes > [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47] > > > It looked pretty clear to me, till the time I decided to make some changes to it %))) > > Ok this is the case: > > As you can see the first line's comprehension produces a list, that includes all the multiplications of "i" (that range(2,8) ) in range (i*2, 50, i). > So I get this pattern: noprimes = = [4, 6, 8.....48, 6, 9,12.... ]. > The change that I tried to apply to this comprehension would lead to the following pattern: noprimes = = [[4, 6,8...48], [6, 9, 12....], ....,[some numbers]] > > But despite my struggling on it for the whole day, I haven't got to the desirable result(using comprehensions only) > > Please, don't get me wrong, I'm not a lazy one (just a beginner). > > In my case, I made some googling, and found some patterns for matrices, that look this one(for example): > > Matrix = [[0 for x in range(5)] for x in range(5)] > > But when I tried to use square brackets with my code, it yields an error about definition of "i", for instance: > > File "<pyshell#30>", line 1, in <module> > noprimes = [[j for i in range(2, 8)] for j in range(i*2, 50, i)] > NameError: name 'i' is not defined. Is this what you want? >>> [[j for j in range(i*2, 50, i)] for i in range(2,8)] [[4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48], [6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48], [8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48], [10, 15, 20, 25, 30, 35, 40, 45], [12, 18, 24, 30, 36, 42, 48], [14, 21, 28, 35, 42, 49]] [I am not sure what you are trying -- just making local changes to the ZF to make it work]
[toc] | [prev] | [next] | [standalone]
| From | "Ivan Evstegneev" <webmailgroups@gmail.com> |
|---|---|
| Date | 2014-11-23 17:37 +0200 |
| Message-ID | <mailman.16188.1416757120.18130.python-list@python.org> |
| In reply to | #81368 |
>Is this what you want?
>
>>>> [[j for j in range(i*2, 50, i)] for i in range(2,8)]
>[[4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40,
42, 44, 46, 48], [6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48],
[8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48], [10, >15, 20, 25, 30, 35, 40,
45], [12, 18, 24, 30, 36, 42, 48], [14, 21, 28, 35, 42, 49]]
>[I am not sure what you are trying -- just making local changes to the ZF
to make it work]
>https://mail.python.org/mailman/listinfo/python-list
Yes, awesome. Thanks.
But it breaks all the picture that I've built in my head about comps till
now...
As I know from books and googling, the comps main idea looks approximately
like this:
[target <--main loop<--nested loop/s (and maybe some conditions)] Am I
right?
But your code looks somehow inverted to me o_0
Like:
[[target with nested loop] <--- main loop with initial values for target]
On the other hand, if I'm comparing to my tryouts:
noprimes = [[j for i in range(2, 8)] for j in range(i*2, 50, i)]
It looks same but the variables are not separated, so it definitely was not
defined....
Sincerely,
Ivan
-----Original Message-----
From: Python-list
[mailto:python-list-bounces+webmailgroups=gmail.com@python.org] On Behalf Of
Rustom Mody
Sent: Sunday, November 23, 2014 17:09
To: python-list@python.org
Subject: Re: Comprehension with two variables - explanation needed
On Sunday, November 23, 2014 8:28:16 PM UTC+5:30, Ivan Evstegneev wrote:
> Hello guys,
>
> I would like to ask you for some explanations on comprehensions.
> (Don't be scared, it just some particular example ^_^)
>
> I found this little "find prime number" example over the internet:
>
> >>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
> >>> primes = [x for x in range(2, 50) if x not in noprimes] print
> >>> primes
> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
>
>
> It looked pretty clear to me, till the time I decided to make some
> changes to it %)))
>
> Ok this is the case:
>
> As you can see the first line's comprehension produces a list, that
includes all the multiplications of "i" (that range(2,8) ) in range (i*2,
50, i).
> So I get this pattern: noprimes = = [4, 6, 8.....48, 6, 9,12.... ].
> The change that I tried to apply to this comprehension would lead to
> the following pattern: noprimes = = [[4, 6,8...48], [6, 9, 12....],
> ....,[some numbers]]
>
> But despite my struggling on it for the whole day, I haven't got to
> the desirable result(using comprehensions only)
>
> Please, don't get me wrong, I'm not a lazy one (just a beginner).
>
> In my case, I made some googling, and found some patterns for matrices,
that look this one(for example):
>
> Matrix = [[0 for x in range(5)] for x in range(5)]
>
> But when I tried to use square brackets with my code, it yields an error
about definition of "i", for instance:
>
> File "<pyshell#30>", line 1, in <module> noprimes = [[j for i in
> range(2, 8)] for j in range(i*2, 50, i)]
> NameError: name 'i' is not defined.
Is this what you want?
>>> [[j for j in range(i*2, 50, i)] for i in range(2,8)]
[[4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40,
42, 44, 46, 48], [6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48],
[8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48], [10, 15, 20, 25, 30, 35, 40,
45], [12, 18, 24, 30, 36, 42, 48], [14, 21, 28, 35, 42, 49]]
[I am not sure what you are trying -- just making local changes to the ZF to
make it work]
--
https://mail.python.org/mailman/listinfo/python-list
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-11-24 02:42 +1100 |
| Message-ID | <mailman.16189.1416757339.18130.python-list@python.org> |
| In reply to | #81368 |
On Mon, Nov 24, 2014 at 2:37 AM, Ivan Evstegneev <webmailgroups@gmail.com> wrote: > As I know from books and googling, the comps main idea looks approximately > like this: > > [target <--main loop<--nested loop/s (and maybe some conditions)] Am I > right? > > But your code looks somehow inverted to me o_0 > > Like: > > [[target with nested loop] <--- main loop with initial values for target] Your analysis is correct, and it's because of the bracketing. Just as you learned back in maths class (or math class, if you're that sort), you start from the innermost brackets and work your way out. In fact, the nested example starts with the main loop, and for each value it goes through, it creates the entire inner comprehension. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Skip Montanaro <skip.montanaro@gmail.com> |
|---|---|
| Date | 2014-11-23 09:45 -0600 |
| Message-ID | <mailman.16191.1416757555.18130.python-list@python.org> |
| In reply to | #81368 |
[Multipart message — attachments visible in raw view] — view raw
> But it breaks all the picture that I've built in my head about comps till > now... Note that list comprehensions are little more than syntactic sugar for for loops. If you're having terrible writing or understanding one, especially a compound one like your example, it can help to write it as a (nested) for loop, then covert it (perhaps incrementally) to the list comp form. Skip
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2014-11-23 10:57 -0500 |
| Message-ID | <roy-B11F64.10563923112014@news.panix.com> |
| In reply to | #81378 |
In article <mailman.16191.1416757555.18130.python-list@python.org>, Skip Montanaro <skip.montanaro@gmail.com> wrote: > > But it breaks all the picture that I've built in my head about comps till > > now... > > Note that list comprehensions are little more than syntactic sugar for for > loops. If you're having terrible writing or understanding one, especially a > compound one like your example, it can help to write it as a (nested) for > loop, then covert it (perhaps incrementally) to the list comp form. Or not. If it was complicated enough that you needed to loopify it to understand what it's doing, have pity on the next person who has to maintain your code and leave it as a loop :-) My general rule for code hygiene is, "If I have to think about whether something is too complicated, it is".
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2014-11-23 08:45 -0800 |
| Message-ID | <07f25264-1286-4d98-820c-949dba711248@googlegroups.com> |
| In reply to | #81380 |
On Sunday, November 23, 2014 9:27:22 PM UTC+5:30, Roy Smith wrote:
> Skip Montanaro wrote:
>
> > > But it breaks all the picture that I've built in my head about comps till
> > > now...
> >
> > Note that list comprehensions are little more than syntactic sugar for for
> > loops. If you're having terrible writing or understanding one, especially a
> > compound one like your example, it can help to write it as a (nested) for
> > loop, then covert it (perhaps incrementally) to the list comp form.
>
> Or not. If it was complicated enough that you needed to loopify it to
> understand what it's doing, have pity on the next person who has to
> maintain your code and leave it as a loop :-)
>
> My general rule for code hygiene is, "If I have to think about whether
> something is too complicated, it is".
[I guess I am in the minority here... anyways... here goes]
1. I find comprehensions are harder than for-loops -- corollary to
functional code is easier than imperative --
corollary to time is a major headache. If the problem does not
involve time the solution should try to avoid it
2. "List comprehensions are syntactic sugar for for loops"
Cannot technically quarrel with that as that is the position of the official
docs.
However to me it puts the cart before the horse.
Its like saying that
def foo(x): return x+1
is just the same as
0 LOAD_FAST 0 (x)
3 LOAD_CONST 1 (1)
6 BINARY_ADD
7 RETURN_VALUE
(output of dis)
That may be the case but it seems (to me at least) to defeat the purpose
of using an hi-level language.
3. So how should one think of list comprehensions?
As a python/executable version of 'set-builder notation'
http://en.wikipedia.org/wiki/Set-builder_notation
4. Finally to the OP (assuming you wanted a prime-number generator)
Heres a solution for your consideration.
First a one-line solution in haskell
sieve (p:xs) = p:sieve [x | x <- xs, x `mod` p /= 0]
Call with sieve [2..]
Now a pythonification of that
def n2s(): # natural nos from 2; ie [2..]
i=2
while True:
yield i
i+=1
def sieve(l):
p = next(l)
yield p
yield from sieve (x for x in l if x % p != 0)
Call as
for p in sieve(n2s()): print(p)
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2014-11-23 09:17 -0800 |
| Message-ID | <40dd9920-ec78-4ebe-865a-e9f7c9c9a7d1@googlegroups.com> |
| In reply to | #81386 |
On Sunday, November 23, 2014 10:15:51 PM UTC+5:30, Rustom Mody wrote: > 1. I find comprehensions are harder than for-loops -- Heh! Meant to say 'easier' of course...
[toc] | [prev] | [next] | [standalone]
| From | "Ivan Evstegneev" <webmailgroups@gmail.com> |
|---|---|
| Date | 2014-11-23 19:27 +0200 |
| Message-ID | <mailman.16201.1416764650.18130.python-list@python.org> |
| In reply to | #81386 |
Got the main idea.
Still need to "chew it up" in depth. (As I mentioned I'm a beginner.... EE
student, so please excuse me for my "lameness" ^_^)
-----Original Message-----
From: Python-list
[mailto:python-list-bounces+webmailgroups=gmail.com@python.org] On Behalf Of
Rustom Mody
Sent: Sunday, November 23, 2014 18:46
To: python-list@python.org
Subject: Re: Comprehension with two variables - explanation needed
On Sunday, November 23, 2014 9:27:22 PM UTC+5:30, Roy Smith wrote:
> Skip Montanaro wrote:
>
> > > But it breaks all the picture that I've built in my head about
> > > comps till now...
> >
> > Note that list comprehensions are little more than syntactic sugar
> > for for loops. If you're having terrible writing or understanding
> > one, especially a compound one like your example, it can help to
> > write it as a (nested) for loop, then covert it (perhaps incrementally)
to the list comp form.
>
> Or not. If it was complicated enough that you needed to loopify it to
> understand what it's doing, have pity on the next person who has to
> maintain your code and leave it as a loop :-)
>
> My general rule for code hygiene is, "If I have to think about whether
> something is too complicated, it is".
[I guess I am in the minority here... anyways... here goes]
1. I find comprehensions are harder than for-loops -- corollary to
functional code is easier than imperative -- corollary to time is a major
headache. If the problem does not involve time the solution should try to
avoid it
2. "List comprehensions are syntactic sugar for for loops"
Cannot technically quarrel with that as that is the position of the official
docs.
However to me it puts the cart before the horse.
Its like saying that
def foo(x): return x+1
is just the same as
0 LOAD_FAST 0 (x)
3 LOAD_CONST 1 (1)
6 BINARY_ADD
7 RETURN_VALUE
(output of dis)
That may be the case but it seems (to me at least) to defeat the purpose of
using an hi-level language.
3. So how should one think of list comprehensions?
As a python/executable version of 'set-builder notation'
http://en.wikipedia.org/wiki/Set-builder_notation
4. Finally to the OP (assuming you wanted a prime-number generator) Heres a
solution for your consideration.
First a one-line solution in haskell
sieve (p:xs) = p:sieve [x | x <- xs, x `mod` p /= 0]
Call with sieve [2..]
Now a pythonification of that
def n2s(): # natural nos from 2; ie [2..]
i=2
while True:
yield i
i+=1
def sieve(l):
p = next(l)
yield p
yield from sieve (x for x in l if x % p != 0)
Call as
for p in sieve(n2s()): print(p)
--
https://mail.python.org/mailman/listinfo/python-list
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2014-11-24 04:42 +0000 |
| Message-ID | <5472b74d$0$12979$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #81386 |
On Sun, 23 Nov 2014 08:45:39 -0800, Rustom Mody wrote:
> 2. "List comprehensions are syntactic sugar for for loops" Cannot
> technically quarrel with that as that is the position of the official
> docs.
> However to me it puts the cart before the horse. Its like saying that
>
> def foo(x): return x+1
>
> is just the same as
>
> 0 LOAD_FAST 0 (x)
> 3 LOAD_CONST 1 (1)
> 6 BINARY_ADD
> 7 RETURN_VALUE
>
>
> (output of dis)
The two situations are not related. The output of dis is an
implementation detail. Try running it under IronPython or Jython and see
what you get. Even in CPython, it is still an implementation detail
subject to change. Today dis() returns the above, tomorrow it may return:
0 LOAD_GLOBAL 0 (x)
3 INCREMENT
5 RETURN_VALUE
(say), and the Python code remains the same even though the byte code is
different.
Whereas the statement that "comprehensions are syntactic sugar for for-
loops" is a statement about the semantics of comprehensions. It's a
language promise, part of the API of Python, and not subject to change
without a period of deprecation. It is a promise that
[expression for name in sequence]
is closely equivalent to:
for name in sequence:
expression
(They are not *identical* because list comprehensions collect the result
of expression into a list, set comprehensions collect them into a set,
etc. But the actual looping part is the same.)
> 3. So how should one think of list comprehensions?
> As a python/executable version of 'set-builder notation'
> http://en.wikipedia.org/wiki/Set-builder_notation
For those who learned, and remember, set-builder notation, that is an
excellent analogy.
> 4. Finally to the OP (assuming you wanted a prime-number generator)
> Heres a solution for your consideration.
>
> First a one-line solution in haskell
>
> sieve (p:xs) = p:sieve [x | x <- xs, x `mod` p /= 0]
Don't use that! That is a horribly inefficient way to generate primes.
Mathematically, it is a version of Euler's Sieve. It is sometimes wrongly
described as "Sieve of Eratosthenes", but that is wrong. Due to it's
horrible performance, Melissa O'Neill calls this the "Sleight on
Eratosthenes":
http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf
Asymptotic behaviour of this is O(N**2/(log N)**2) which is worse than
trial division and only *marginally* better than this stupidly naive
version:
def primes0():
i = 2
yield i
while True:
i += 1
composite = False
for p in range(2, i):
if i%p == 0:
composite = True
if not composite: # It must be a prime.
yield i
> Call with sieve [2..]
>
> Now a pythonification of that
[...]
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-11-24 15:51 +1100 |
| Message-ID | <mailman.16222.1416804702.18130.python-list@python.org> |
| In reply to | #81423 |
On Mon, Nov 24, 2014 at 3:42 PM, Steven D'Aprano <steve@pearwood.info> wrote: > Today dis() returns the above, tomorrow it may return: > > 0 LOAD_GLOBAL 0 (x) > 3 INCREMENT > 5 RETURN_VALUE > > (say), and the Python code remains the same even though the byte code is > different. I hope not! The x in the original function was a local, not a global, and if dis.dis() says LOAD_GLOBAL for something that's not global, it would be *very* confusing! :) But yes, CPython could grow an INCREMENT bytecode, and it'd not break anything. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2014-11-25 09:20 +1100 |
| Message-ID | <5473af18$0$13004$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #81426 |
Chris Angelico wrote: > On Mon, Nov 24, 2014 at 3:42 PM, Steven D'Aprano <steve@pearwood.info> > wrote: >> Today dis() returns the above, tomorrow it may return: >> >> 0 LOAD_GLOBAL 0 (x) >> 3 INCREMENT >> 5 RETURN_VALUE >> >> (say), and the Python code remains the same even though the byte code is >> different. > > I hope not! The x in the original function was a local, not a global, D'oh! I mean, yes, that was a test to see if you were paying attention, and you have passed! Well done. *whistles nonchalantly* -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2014-11-23 22:47 -0800 |
| Message-ID | <24e2bcc9-9b48-4f7b-a8aa-a7ad8a7051d1@googlegroups.com> |
| In reply to | #81423 |
On Monday, November 24, 2014 10:13:04 AM UTC+5:30, Steven D'Aprano wrote: > On Sun, 23 Nov 2014 08:45:39 -0800, Rustom Mody wrote: > > First a one-line solution in haskell > > > > sieve (p:xs) = p:sieve [x | x <- xs, x `mod` p /= 0] > > Don't use that! That is a horribly inefficient way to generate primes. > > Mathematically, it is a version of Euler's Sieve. It is sometimes wrongly > described as "Sieve of Eratosthenes", but that is wrong. Due to it's > horrible performance, Melissa O'Neill calls this the "Sleight on > Eratosthenes": > > http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf Thanks for that link -- I'll need to look at it carefully
[toc] | [prev] | [next] | [standalone]
| From | Dan Stromberg <drsalists@gmail.com> |
|---|---|
| Date | 2014-11-24 16:42 -0800 |
| Message-ID | <mailman.16260.1416876136.18130.python-list@python.org> |
| In reply to | #81423 |
On Sun, Nov 23, 2014 at 8:42 PM, Steven D'Aprano <steve@pearwood.info> wrote: > On Sun, 23 Nov 2014 08:45:39 -0800, Rustom Mody wrote: >> First a one-line solution in haskell >> >> sieve (p:xs) = p:sieve [x | x <- xs, x `mod` p /= 0] > > Don't use that! That is a horribly inefficient way to generate primes. > > Mathematically, it is a version of Euler's Sieve. It is sometimes wrongly > described as "Sieve of Eratosthenes", but that is wrong. Due to it's > horrible performance, Melissa O'Neill calls this the "Sleight on > Eratosthenes": I don't read Haskell, but here's a Sieve (or at least I thought it was a Sieve) and a few other prime-related things: http://stromberg.dnsalias.org/~dstromberg/primes/
[toc] | [prev] | [next] | [standalone]
| From | Skip Montanaro <skip.montanaro@gmail.com> |
|---|---|
| Date | 2014-11-23 10:45 -0600 |
| Message-ID | <mailman.16197.1416761116.18130.python-list@python.org> |
| In reply to | #81380 |
On Sun, Nov 23, 2014 at 9:57 AM, Roy Smith <roy@panix.com> wrote: > > If it was complicated enough that you needed to loopify it to > understand what it's doing, have pity on the next person who has to > maintain your code and leave it as a loop Well, sure. I was mostly trying to give Ivan a path out of the weeds. Poking through the code I'm involved with at work, using a crude measuring stick (a couple regular expressions) I found over 1400 one line list comprehensions, those which matched this regular expression: \[.* for .*\] OTOH, I only found 14 with two "for" keywords: \[.* for .* for .*\] (There may well have been more nested loop list comprehensions, simply because it's hard to cram the full listcomp into 80 columns, my self-imposed column limit.) In my experience, list comprehensions rapidly get unwieldy once you get to nesting them. I generally unravel such items into a nested set of for loops. Skip
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2014-11-23 12:08 -0500 |
| Message-ID | <mailman.16200.1416762503.18130.python-list@python.org> |
| In reply to | #81380 |
We seem to be somewhat more liberal about nested comprehensions here, but I can't say I'm proud of that :-) 906 Python source files, 109k lines. $ find . -name '*.py' | xargs grep '\[.* for .*\]' | wc -l 729 $ find . -name '*.py' | xargs grep '\[.* for .* for .*\]' | wc -l 46 Without naming names, a quick look into our nested comprehensions with "hg blame" shows a very strong correlation between "people who wrote many nested comprehensions" and "people who's code I find difficult to read in general". I see one of these that has my name on the commit: report = [keys] + [[line[key] for key in keys] for line in results] but I'm glad to report that this was merely some third-party code that I imported into our repo. Whew, that was close! On Nov 23, 2014, at 11:45 AM, Skip Montanaro wrote: > On Sun, Nov 23, 2014 at 9:57 AM, Roy Smith <roy@panix.com> wrote: >> >> If it was complicated enough that you needed to loopify it to >> understand what it's doing, have pity on the next person who has to >> maintain your code and leave it as a loop > > Well, sure. I was mostly trying to give Ivan a path out of the weeds. > Poking through the code I'm involved with at work, using a crude > measuring stick (a couple regular expressions) I found over 1400 one > line list comprehensions, those which matched this regular expression: > > \[.* for .*\] > > OTOH, I only found 14 with two "for" keywords: > > \[.* for .* for .*\] > > (There may well have been more nested loop list comprehensions, simply > because it's hard to cram the full listcomp into 80 columns, my > self-imposed column limit.) > > In my experience, list comprehensions rapidly get unwieldy once you > get to nesting them. I generally unravel such items into a nested set > of for loops. > > Skip > -- Roy Smith roy@panix.com
[toc] | [prev] | [next] | [standalone]
| From | Jon Ribbens <jon+usenet@unequivocal.co.uk> |
|---|---|
| Date | 2014-11-23 17:46 +0000 |
| Message-ID | <slrnm747bp.jls.jon+usenet@frosty.unequivocal.co.uk> |
| In reply to | #81380 |
On 2014-11-23, Roy Smith <roy@panix.com> wrote: > In article <mailman.16191.1416757555.18130.python-list@python.org>, > Skip Montanaro <skip.montanaro@gmail.com> wrote: >> > But it breaks all the picture that I've built in my head about comps till >> > now... >> >> Note that list comprehensions are little more than syntactic sugar for for >> loops. If you're having terrible writing or understanding one, especially a >> compound one like your example, it can help to write it as a (nested) for >> loop, then covert it (perhaps incrementally) to the list comp form. > > Or not. If it was complicated enough that you needed to loopify it to > understand what it's doing, have pity on the next person who has to > maintain your code and leave it as a loop :-) > > My general rule for code hygiene is, "If I have to think about whether > something is too complicated, it is". My reminder rule for nested comprehensions is "Which way do you instinctively think they should nest and makes logical sense? They don't work that way."
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web