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


Groups > comp.lang.python > #81370

Re: Comprehension with two variables - explanation needed

Path csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.xs4all.nl!newsfeed4a.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail
Return-Path <rosuav@gmail.com>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.000
X-Spam-Evidence '*H*': 1.00; '*S*': 0.00; '16,': 0.03; 'algorithm': 0.04; 'patterns': 0.04; 'skip:[ 20': 0.04; 'explicitly': 0.05; 'root': 0.05; '21,': 0.07; 'explicit': 0.07; 'nested': 0.07; 'subject:two': 0.07; '22,': 0.09; '34,': 0.09; '40,': 0.09; 'calls.': 0.09; 'executed': 0.09; 'function,': 0.09; 'internet:': 0.09; 'level:': 0.09; 'list).': 0.09; 'tmp': 0.09; 'wrong,': 0.09; 'translate': 0.10; 'cc:addr:python-list': 0.11; 'python': 0.11; 'changes': 0.15; '(just': 0.16; '23,': 0.16; '24,': 0.16; '32,': 0.16; '33,': 0.16; '36,': 0.16; '37,': 0.16; '39,': 0.16; '42,': 0.16; '46,': 0.16; '50)': 0.16; '[2,': 0.16; 'any)?': 0.16; 'brackets': 0.16; 'comp': 0.16; 'deduced': 0.16; 'defined.': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'guys,': 0.16; 'instance:': 0.16; 'iteration': 0.16; 'iterator': 0.16; 'itself,': 0.16; 'ivan': 0.16; 'i\xe2\x80\x99m': 0.16; 'loops': 0.16; 'mean,': 0.16; 'nameerror:': 0.16; 'nesting': 0.16; 'once;': 0.16; 'only)': 0.16; 'utterly': 0.16; 'wrote:': 0.18; 'variable': 0.18; 'all,': 0.19; 'not,': 0.20; 'solution.': 0.20; '(the': 0.22; '>>>': 0.22; 'code,': 0.22; 'example': 0.22; 'cc:addr:python.org': 0.22; 'print': 0.22; 'error': 0.23; '31,': 0.24; 'stopping': 0.24; 'fairly': 0.24; 'initial': 0.24; 'mon,': 0.24; 'cc:2**0': 0.24; '15,': 0.26; 'first,': 0.26; 'this:': 0.26; 'header:In-Reply-To:1': 0.27; 'tried': 0.27; 'function': 0.29; 'leave': 0.29; 'am,': 0.29; "doesn't": 0.30; 'list:': 0.30; 'moved': 0.30; 'message-id:@mail.gmail.com': 0.30; '"",': 0.31; '13,': 0.31; '25,': 0.31; '50,': 0.31; 'minor': 0.31; 'yields': 0.31; 'file': 0.32; 'lists': 0.32; 'there.': 0.32; "we're": 0.32; 'another': 0.32; 'quite': 0.32; 'running': 0.33; 'problem': 0.35; 'subject:with': 0.35; "can't": 0.35; 'created': 0.35; 'case,': 0.35; 'definition': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; '14,': 0.36; 'possible': 0.36; 'so,': 0.37; 'list': 0.37; 'easily': 0.37; 'performance': 0.37; 'starting': 0.37; 'nov': 0.38; 'subject:needed': 0.38; 'back': 0.62; 'name': 0.63; 'such': 0.63; 'skip:n 10': 0.64; 'more': 0.64; 'different': 0.65; '30,': 0.65; 'skip:\xe2 10': 0.65; 'details': 0.65; 'here': 0.66; '20,': 0.68; '26,': 0.68; '8bit%:40': 0.68; 'fact,': 0.69; 'applying': 0.72; 'further,': 0.74; 'prime': 0.74; 'square': 0.74; 'walk': 0.74; 'increase': 0.74; 'hand': 0.80; 'counts': 0.83; '^_^': 0.84; 'here)': 0.84; 'leak': 0.84; 'composite': 0.91; 'don\xe2\x80\x99t': 0.91; 'lazy': 0.91; 'to:none': 0.92; 'differences': 0.93; 'ultimate': 0.93
DKIM-Signature v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type:content-transfer-encoding; bh=K+TFX6zFeArNCXTpiYE0pMIToPo6J+OkAxpnMU4TIMo=; b=jpO49b0NRx2sjWDMAwZ1BCQyMOihHo1bnTGiql17oJLiJmHbhn8t2WOaHFjV6K9YCW RRF59GEzjLffS1XQigI9+Wdfk31GNVBszGbDCbWEkUMW51Jq9Fr+aENqMhiNFGGel0R1 weeXqnFfBH8sbtr0PRj7J2oM/GbB8CWvJ0DxQgNTQ4JN9l3WXXGo15pHhOtq0vbdfmzR GlFREL0eEmxrh3H3JTUl+eaqN/WeZhR8Wtl7G6I4ZCKRNZFO6y0mR62WlMyPsi6LcDn1 DZS0OuillgIVJ7WXA0o/K4jLOzuJqjzRO0upcUmvoEjQCjc4UzPicqe/O1lsW4nAm6vY sn6g==
MIME-Version 1.0
X-Received by 10.107.134.39 with SMTP id i39mr13682664iod.53.1416756095456; Sun, 23 Nov 2014 07:21:35 -0800 (PST)
In-Reply-To <002001d0072d$b9b5da50$2d218ef0$@gmail.com>
References <002001d0072d$b9b5da50$2d218ef0$@gmail.com>
Date Mon, 24 Nov 2014 02:21:35 +1100
Subject Re: Comprehension with two variables - explanation needed
From Chris Angelico <rosuav@gmail.com>
Cc "python-list@python.org" <python-list@python.org>
Content-Type text/plain; charset=UTF-8
Content-Transfer-Encoding quoted-printable
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.15
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <https://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list/>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <https://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.16186.1416756098.18130.python-list@python.org> (permalink)
Lines 130
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1416756098 news.xs4all.nl 2849 [2001:888:2000:d::a6]:34466
X-Complaints-To abuse@xs4all.nl
Xref csiph.com comp.lang.python:81370

Show key headers only | View raw


On Mon, Nov 24, 2014 at 1:56 AM, Ivan Evstegneev
<webmailgroups@gmail.com> 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]

Okay, this is a pretty ham-fisted way of enumerating prime numbers,
but let me walk you through it. First, let's look at the composite
numbers (the 'noprimes' list). That comprehension is identical (apart
from some details that don't matter here) to this:

noprimes = []
for i in range(2,8):
    for j in range(i*2, 50, i):
        noprimes.append(j)

So, as you correctly deduced below, what you have is this list:
[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]

The inner loop (with j as its iteration variable) counts up in
increments of i, starting at twice i, stopping once it's gone past
fifty. That means it's every multiple of i other than i itself, which
means these are by definition composite numbers. Note that quite a few
of the numbers are coming up more than once; this would be more
efficient as a set comprehension, but leave that aside for now.

Note also that the range for i has to go as far as the square root of
the number we're working with - we have to go as far as 7*7==49. If
you want primes to some higher cap, say 100, you'd need to also
increase that, eg range(2,11).

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

The inner lists there can be created more simply, since you're working
with integers:

[[0]*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.

That's because you have your nesting backwards. Instead of having the
for loops running left-to-right, they now are explicitly bracketed to
be the other way around. This is more like:

noprimes = []
for j in range(i*2, 50, i):
    noprimes.append([j for i in range(2, 8)])

which can be unrolled another level:

noprimes = []
for j in range(i*2, 50, i):
    tmp = []
    for i in range(2, 8):
        tmp.append(j)
    noprimes.append(tmp)

Now you can see why i doesn't exist there.

> 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:
>
> Yep, this the “classical” way for me, on the other hand I have the feeling, that this is not, the ultimate solution. ^_^

In fact, this is exactly right, and now you can easily translate that
back to list comp syntax:

noprimes = [list(range(i*2,50,i)) for i in range(2,8)]

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

Don't worry about speed of function calls. The algorithm used here is
so utterly appalling that it's going to get in your way long before
the performance of Python will. :)

List comprehensions are fairly readily convertible to and from
explicit loops. There are a couple of minor differences (a list comp
is actually executed inside a nested function, so the loop iterator
variable can't leak out), but generally, if you're having trouble,
just unroll the comprehension into a loop and see if it makes more
sense.

ChrisA

Back to comp.lang.python | Previous | Next | Find similar | Unroll thread


Thread

Re: Comprehension with two variables - explanation needed Chris Angelico <rosuav@gmail.com> - 2014-11-24 02:21 +1100

csiph-web