Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #82752 > unrolled thread
| Started by | Chris Angelico <rosuav@gmail.com> |
|---|---|
| First post | 2014-12-22 17:06 +1100 |
| Last post | 2014-12-22 09:45 -0800 |
| Articles | 6 — 3 participants |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: List Comprehensions Chris Angelico <rosuav@gmail.com> - 2014-12-22 17:06 +1100
Re: List Comprehensions Roy Smith <roy@panix.com> - 2014-12-22 08:07 -0500
Re: List Comprehensions Chris Angelico <rosuav@gmail.com> - 2014-12-23 00:21 +1100
Re: List Comprehensions Rustom Mody <rustompmody@gmail.com> - 2014-12-22 06:58 -0800
Re: List Comprehensions Chris Angelico <rosuav@gmail.com> - 2014-12-23 02:07 +1100
Re: List Comprehensions Rustom Mody <rustompmody@gmail.com> - 2014-12-22 09:45 -0800
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-12-22 17:06 +1100 |
| Subject | Re: List Comprehensions |
| Message-ID | <mailman.17109.1419228400.18130.python-list@python.org> |
On Mon, Dec 22, 2014 at 4:42 PM, Ganesh Pal <ganesh1pal@gmail.com> wrote: > (a) I was trying to reduce the below piece of code using List comprehension > ? Any suggestion please let me know > > > for opt in options: > opt['result'] = Queue.Queue() > tmp_thread = pause.Thread(opt) > threads.append(tmp_thread) > tmp_thread.start() > > (b) Is there anything that I need to consider while using list > comprehension with threads ? Your code is doing several things at once, so it's probably not worth trying to turn it into a comprehension. I don't think it needs to be shortened, anyway; looks fine to me. ChrisA
[toc] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2014-12-22 08:07 -0500 |
| Message-ID | <roy-8A482E.08070922122014@news.panix.com> |
| In reply to | #82752 |
In article <mailman.17109.1419228400.18130.python-list@python.org>, Chris Angelico <rosuav@gmail.com> wrote: > On Mon, Dec 22, 2014 at 4:42 PM, Ganesh Pal <ganesh1pal@gmail.com> wrote: > > (a) I was trying to reduce the below piece of code using List comprehension > > ? Any suggestion please let me know > > > > > > for opt in options: > > opt['result'] = Queue.Queue() > > tmp_thread = pause.Thread(opt) > > threads.append(tmp_thread) > > tmp_thread.start() > > > > (b) Is there anything that I need to consider while using list > > comprehension with threads ? > > Your code is doing several things at once, so it's probably not worth > trying to turn it into a comprehension. I don't think it needs to be > shortened, anyway; looks fine to me. I pretty much agree with Chris. If I were to refactor this, however, I would probably pull the body of the loop out into a function, then it might make sense to do the accumulation of threads in a comprehension: def init_thread(opt): opt['result'] = Queue.Queue() thread = pause.Thread(opt) thread.start() return thread threads = [init_thread(opt) for opt in options] But, really, I think the way you had it originally was cleaner.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-12-23 00:21 +1100 |
| Message-ID | <mailman.17118.1419254490.18130.python-list@python.org> |
| In reply to | #82768 |
On Tue, Dec 23, 2014 at 12:07 AM, Roy Smith <roy@panix.com> wrote:
> def init_thread(opt):
> opt['result'] = Queue.Queue()
> thread = pause.Thread(opt)
> thread.start()
> return thread
>
> threads = [init_thread(opt) for opt in options]
If this is, indeed, just initializing the threads, then this might
make sense. Or alternatively, if you could subclass threading.Thread
and do all the work in __init__, then you could simply construct them
all:
class whatever(thread.Thread):
def __init__(self, opt):
self.queue = Queue.Queue()
self.opt = opt
super().__init__()
self.start()
threads = [whatever(opt) for opt in options]
Just as long as you can come up with a sane name for the class, or the
initializer function, that makes sense without the list comp.
Incidentally, this is part of what I was saying about side effects
being okay in a list comp; either Roy's or my examples here would be a
list comp that has the side effect of starting a bunch of threads, and
I don't see it as being at all problematic. Just don't use a list comp
for _just_ the side effects.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2014-12-22 06:58 -0800 |
| Message-ID | <b1bccab6-7025-41fd-b0a1-d19e1fef41da@googlegroups.com> |
| In reply to | #82771 |
On Monday, December 22, 2014 6:52:12 PM UTC+5:30, Chris Angelico wrote: > On Tue, Dec 23, 2014 at 12:07 AM, Roy Smith wrote: > > def init_thread(opt): > > opt['result'] = Queue.Queue() > > thread = pause.Thread(opt) > > thread.start() > > return thread > > > > threads = [init_thread(opt) for opt in options] > > If this is, indeed, just initializing the threads, then this might > make sense. Or alternatively, if you could subclass threading.Thread > and do all the work in __init__, then you could simply construct them > all: > > class whatever(thread.Thread): > def __init__(self, opt): > self.queue = Queue.Queue() > self.opt = opt > super().__init__() > self.start() > > threads = [whatever(opt) for opt in options] > > Just as long as you can come up with a sane name for the class, or the > initializer function, that makes sense without the list comp. > > Incidentally, this is part of what I was saying about side effects > being okay in a list comp; either Roy's or my examples here would be a > list comp that has the side effect of starting a bunch of threads, and > I don't see it as being at all problematic. I see it as "Ewww!!!" If you consider side-effecting comprehensions as kosher, then a next conclusion is naturally going to be that multiple generator comprehensions are confusing and therefore not kosher -- a very unfortunate conclusion IMHO. Steven's > results = [function(item) for item in items] > If the called function has side-effects, a list comp is not a > good solution. > If you don't care about the results, a list comp is not a good solution. should be standard fare for beginners beginners befuddled by comprehensions To the OP: Comprehensions are not for-statements any more than conditional expressions are if-statements. In both cases you want the first for the value, the second for the effect. Its another matter that you can usually refactor one into the other. The larger context of your code is not visible so cant elaborate more on that now...
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-12-23 02:07 +1100 |
| Message-ID | <mailman.17120.1419260860.18130.python-list@python.org> |
| In reply to | #82775 |
On Tue, Dec 23, 2014 at 1:58 AM, Rustom Mody <rustompmody@gmail.com> wrote: > If you consider side-effecting comprehensions as kosher, > then a next conclusion is naturally going to be that > multiple generator comprehensions are confusing and therefore > not kosher -- a very unfortunate conclusion IMHO. Why does that follow? What has that to do with side effects? ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2014-12-22 09:45 -0800 |
| Message-ID | <513e14f1-cde3-4564-bdb6-285f55969a85@googlegroups.com> |
| In reply to | #82776 |
On Monday, December 22, 2014 8:37:50 PM UTC+5:30, Chris Angelico wrote: > On Tue, Dec 23, 2014 at 1:58 AM, Rustom Mody wrote: > > If you consider side-effecting comprehensions as kosher, > > then a next conclusion is naturally going to be that > > multiple generator comprehensions are confusing and therefore > > not kosher -- a very unfortunate conclusion IMHO. > > Why does that follow? What has that to do with side effects? A comprehension means two things 1. There is the standard de-sugaring in terms of for-loops given in the docs that Steven repeated above. 2.There is this picture (needs to be seen in fix-pitch font) [f(x) for x in [x₁ x₂ x₃ … xₙ]] means [x₁ x₂ x₃ … xₙ] ↓ ↓ ↓ ↓ [fx₁ fx₂ x₃ … fxₙ] There are not just two different ways of writing that for-loop -- upwards and downwards -- there are n! ways. And even that assumes that each arrow is atomically and sequentially performed. An assumption quite ok for a sequential machine completely unnecessary for a programmer. Give up that assumption and the ways are infinite IOW the second view is more abstract and programmer friendly than the first in the same way that saying the C expression "x+1" "Adds 1 to the variable x" rather than saying "Its the C version of add 1, %eax" [Why not inc %eax ?] And this despite the fact that mathematical integers and real are rather far removed from C's int and float. IOW white lies are preferable to exact precise gobbledygook. If the semantics of the comprehension depends on the order of the arrows, the comprehension is screwed Shorter technological answer: In Haskell a side-effecting function gets a monadic type -- the type carries the moniker "I am side-effecting" and so it cant be put in to a comprehension without type errors. Now python's type system cannot do what Haskell's can [for better or worse is another matter -- a strong type system can be neat or a pain] Considering that python's comprehensions are cloned from Haskell, it seems fair that Haskell's formal strictures be passed on to beginners at least informally
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web