Re: Rant (was Re: x*x if x10
Diez B. Roggisch wrote: I maybe should paraphrase don't return objects you passed as arguments from a function. The important thing is that a function shouldn't modify any object unless it's the express purpose of the function to do so. You could call this the look but don't touch rule. -- Greg -- http://mail.python.org/mailman/listinfo/python-list
Rant (was Re: x*x if x10
On Sun, 27 Jul 2008 05:24:36 -0700 (PDT), alex23 [EMAIL PROTECTED] wrote: On Jul 27, 10:13 pm, ssecorp [EMAIL PROTECTED] wrote: I have seen somewhere that you can write something like: x*x if x10 but exactly that doesn't work and I can't get any variation to work. It's called a ternary operator. The format is: label = true-value if condition else false-value I've seen the PERL saying/motto/boast, There's more than one way to do it derided on more than one occasion on this group so what's the reason for this additional way to put an if else statement on one line? Are and and or constructions to produce the same effect not supported for this use? And while I'm on my high horse, I'd like to bring up list concatenations. I recently needed to concatenate 5 lists, which doesn't sound a particularly rare requirement to me. My first attempt was a straightforward loop extending an empty list. That worked fine but looked like an awful bulky solution. Afterwards I tried various formulae using reduce , falling foul of the = catch on one occasion. Now I'm not a professional programmer, so there may be good reasons for a single object to have multiple names in a program, but it sounds like a recipe for disaster to me. Getting back to the list concatenation, I finally found the itertools.chain command which is the most compact and fastest (or second fastest by a trivial amount, I can't remember which). Along the way, I must have tried/used half a dozen methods, ...which brings me back my initial PERL comment. There's more than one way to do it in Python, too. DaveM -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
On Sun, Jul 27, 2008 at 10:17 AM, DaveM [EMAIL PROTECTED] wrote: On Sun, 27 Jul 2008 05:24:36 -0700 (PDT), alex23 [EMAIL PROTECTED] wrote: On Jul 27, 10:13 pm, ssecorp [EMAIL PROTECTED] wrote: I have seen somewhere that you can write something like: x*x if x10 but exactly that doesn't work and I can't get any variation to work. It's called a ternary operator. The format is: label = true-value if condition else false-value I've seen the PERL saying/motto/boast, There's more than one way to do it derided on more than one occasion on this group so what's the reason for this additional way to put an if else statement on one line? Are and and or constructions to produce the same effect not supported for this use? In fact the PEP for this construct states: The motivating use case was the prevalance of error-prone attempts to achieve the same effect using and and or. See: http://www.python.org/dev/peps/pep-0308/ Karen -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
DaveM schrieb: On Sun, 27 Jul 2008 05:24:36 -0700 (PDT), alex23 [EMAIL PROTECTED] wrote: On Jul 27, 10:13 pm, ssecorp [EMAIL PROTECTED] wrote: I have seen somewhere that you can write something like: x*x if x10 but exactly that doesn't work and I can't get any variation to work. It's called a ternary operator. The format is: label = true-value if condition else false-value I've seen the PERL saying/motto/boast, There's more than one way to do it derided on more than one occasion on this group so what's the reason for this additional way to put an if else statement on one line? Are and and or constructions to produce the same effect not supported for this use? You obviously aren't aware of the pitfalls regarding the mis-use of or and and for this usage. Try this: a = True b = 1 c = 2 a and b or c 1 a = False a and b or c 2 a = True b = None a and b or c 2 Afterwards I tried various formulae using reduce , falling foul of the = catch on one occasion. Now I'm not a professional programmer, so there may be good reasons for a single object to have multiple names in a program, but it sounds like a recipe for disaster to me. Can you tell us what you mean by several names of one object? You mean this? a = range(10) b = a id(a) == id(b) ? Passing references instead of values is an extremely important concept of many languages, without it you would end up copying most of the time. Getting back to the list concatenation, I finally found the itertools.chain command which is the most compact and fastest (or second fastest by a trivial amount, I can't remember which). Along the way, I must have tried/used half a dozen methods, ...which brings me back my initial PERL comment. There's more than one way to do it in Python, too. Any non-trivial task has that property. I don't know enough perl to have an example ready that shows something that python has only one way of doing and perl has several. But I *do* know that taking the python zen literally is fruitless. Diez -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
DaveM wrote: On Sun, 27 Jul 2008 05:24:36 -0700 (PDT), alex23 [EMAIL PROTECTED] wrote: On Jul 27, 10:13 pm, ssecorp [EMAIL PROTECTED] wrote: I have seen somewhere that you can write something like: x*x if x10 but exactly that doesn't work and I can't get any variation to work. It's called a ternary operator. The format is: label = true-value if condition else false-value I've seen the PERL saying/motto/boast, There's more than one way to do it derided on more than one occasion on this group so what's the reason for this additional way to put an if else statement on one line? Are and and or constructions to produce the same effect not supported for this use? The and and or construct which is equivalent to the ternary operator is quite convoluted and looks nothing like a conditional computation: (C and [A] or [B])[0] This is inefficient, and nearly unreadable, which makes the highly useful ternary operator worthy of a syntactical construct. The [A], [B] and [0] parts are absolutely necessary in the general case where A can have values that Python would consider equivalent to False. If you know A will never be equivalent to False then you can use just this: C and A or B Gary Herron And while I'm on my high horse, I'd like to bring up list concatenations. I recently needed to concatenate 5 lists, which doesn't sound a particularly rare requirement to me. My first attempt was a straightforward loop extending an empty list. That worked fine but looked like an awful bulky solution. Afterwards I tried various formulae using reduce , falling foul of the = catch on one occasion. Now I'm not a professional programmer, so there may be good reasons for a single object to have multiple names in a program, but it sounds like a recipe for disaster to me. Getting back to the list concatenation, I finally found the itertools.chain command which is the most compact and fastest (or second fastest by a trivial amount, I can't remember which). Along the way, I must have tried/used half a dozen methods, ...which brings me back my initial PERL comment. There's more than one way to do it in Python, too. DaveM -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
On Sun, 27 Jul 2008 16:41:19 +0200, Diez B. Roggisch wrote: DaveM schrieb: Getting back to the list concatenation, I finally found the itertools.chain command which is the most compact and fastest (or second fastest by a trivial amount, I can't remember which). Along the way, I must have tried/used half a dozen methods, ...which brings me back my initial PERL comment. There's more than one way to do it in Python, too. Any non-trivial task has that property. I don't know enough perl to have an example ready that shows something that python has only one way of doing and perl has several. But I *do* know that taking the python zen literally is fruitless. I think it should be taken more literally than the wrong reduction to there should be only one way. People tend to forget obvious and preferably all the time. Ciao, Marc 'BlackJack' Rintsch -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
Marc 'BlackJack' Rintsch schrieb: On Sun, 27 Jul 2008 16:41:19 +0200, Diez B. Roggisch wrote: DaveM schrieb: Getting back to the list concatenation, I finally found the itertools.chain command which is the most compact and fastest (or second fastest by a trivial amount, I can't remember which). Along the way, I must have tried/used half a dozen methods, ...which brings me back my initial PERL comment. There's more than one way to do it in Python, too. Any non-trivial task has that property. I don't know enough perl to have an example ready that shows something that python has only one way of doing and perl has several. But I *do* know that taking the python zen literally is fruitless. I think it should be taken more literally than the wrong reduction to there should be only one way. People tend to forget obvious and preferably all the time. Good point. The OP found the obvious way of extending. I wonder what his reasons were to abandon it. Diez -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
I might be misunderstanding OP but: a+b+c+d+e is simple way of concatenating 5 lists... as a function that takes any amount of lists and concatenates them: def concat(*args): c = [] for elem in args: c += elem return c don't know if extend is faster or slower or the same as + : def concat(*args): c = [] for elem in args: c.extend(elem) return c I don't know of a built-in. -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
On Jul 28, 1:26 am, ssecorp [EMAIL PROTECTED] wrote: I might be misunderstanding OP but: a+b+c+d+e is simple way of concatenating 5 lists... as a function that takes any amount of lists and concatenates them: def concat(*args): c = [] for elem in args: c += elem return c don't know if extend is faster or slower or the same as + : def concat(*args): c = [] for elem in args: c.extend(elem) return c I don't know of a built-in. Just to infuriate the OP even further, here's the list comprehension version :) def concat(*args): ... return [elem for arg in args for elem in arg] Hope this helps! -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
On Sun, 27 Jul 2008 16:57:14 +0200, Diez B. Roggisch [EMAIL PROTECTED] wrote: Marc 'BlackJack' Rintsch schrieb: On Sun, 27 Jul 2008 16:41:19 +0200, Diez B. Roggisch wrote: DaveM schrieb: Getting back to the list concatenation, I finally found the itertools.chain command which is the most compact and fastest (or second fastest by a trivial amount, I can't remember which). Along the way, I must have tried/used half a dozen methods, ...which brings me back my initial PERL comment. There's more than one way to do it in Python, too. But I *do* know that taking the python zen literally is fruitless. I think it should be taken more literally than the wrong reduction to there should be only one way. People tend to forget obvious and preferably all the time. Good point. The OP found the obvious way of extending. I wonder what his reasons were to abandon it. You'll have guessed, I'm sure, that I'm not a professional programmer. This was the third rewrite of a program to match candidate groups to examiners on a three day course I run, necessitated on this occasion by a change in the structure of the course. I originally learnt python as I wrote, and some of the early code was ugly and verbose, so once the current rewrite was working I took the opportunity to tidy the code up and document it (yes, I know, but as I said, I'm an amateur). The list concatenation was an itch I couldn't scratch: temp = [] for value in sessexam.values(): temp.extend(value) c_exam = [name for name in set(temp)] #See what I mean about verbose? c_exam.sort() return c_exam Six lines just didn't feel like it ought to be the best way to do something so simple. I liked the attempt below better, but was foolish enough to time it, so that was the end of that. return sorted(list(set(reduce(lambda x, y: x+y, sessexam.values() The current version (below) is a compromise, but I still feel there _ought_ to be a simple one word command to join multiple lists. a = list(set(itertools.chain(*sessexam.values( a.sort() #As I write I'm wondering if I really need it sorted. Hmm... return a DaveM -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
DaveM wrote: On Sun, 27 Jul 2008 16:57:14 +0200, Diez B. Roggisch [EMAIL PROTECTED] wrote: Marc 'BlackJack' Rintsch schrieb: On Sun, 27 Jul 2008 16:41:19 +0200, Diez B. Roggisch wrote: DaveM schrieb: Getting back to the list concatenation, I finally found the itertools.chain command which is the most compact and fastest (or second fastest by a trivial amount, I can't remember which). Along the way, I must have tried/used half a dozen methods, ...which brings me back my initial PERL comment. There's more than one way to do it in Python, too. But I *do* know that taking the python zen literally is fruitless. I think it should be taken more literally than the wrong reduction to there should be only one way. People tend to forget obvious and preferably all the time. Good point. The OP found the obvious way of extending. I wonder what his reasons were to abandon it. You'll have guessed, I'm sure, that I'm not a professional programmer. This was the third rewrite of a program to match candidate groups to examiners on a three day course I run, necessitated on this occasion by a change in the structure of the course. I originally learnt python as I wrote, and some of the early code was ugly and verbose, so once the current rewrite was working I took the opportunity to tidy the code up and document it (yes, I know, but as I said, I'm an amateur). The list concatenation was an itch I couldn't scratch: temp = [] for value in sessexam.values(): temp.extend(value) c_exam = [name for name in set(temp)] #See what I mean about verbose? c_exam.sort() return c_exam Six lines just didn't feel like it ought to be the best way to do something so simple. I liked the attempt below better, but was foolish enough to time it, so that was the end of that. return sorted(list(set(reduce(lambda x, y: x+y, sessexam.values() The current version (below) is a compromise, but I still feel there _ought_ to be a simple one word command to join multiple lists. a = list(set(itertools.chain(*sessexam.values( a.sort() #As I write I'm wondering if I really need it sorted. Hmm... return a Didn't someone already answer that. List addition and sum() both do what you want. A = [1,2,3] B = [4,5,6] C = [7,8,9] A+B+C [1, 2, 3, 4, 5, 6, 7, 8, 9] sum([A,B,C], []) [1, 2, 3, 4, 5, 6, 7, 8, 9] It doesn't get any easier than that. Gary Herron DaveM -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
DaveM schrieb: On Sun, 27 Jul 2008 16:57:14 +0200, Diez B. Roggisch [EMAIL PROTECTED] wrote: Marc 'BlackJack' Rintsch schrieb: On Sun, 27 Jul 2008 16:41:19 +0200, Diez B. Roggisch wrote: DaveM schrieb: Getting back to the list concatenation, I finally found the itertools.chain command which is the most compact and fastest (or second fastest by a trivial amount, I can't remember which). Along the way, I must have tried/used half a dozen methods, ...which brings me back my initial PERL comment. There's more than one way to do it in Python, too. But I *do* know that taking the python zen literally is fruitless. I think it should be taken more literally than the wrong reduction to there should be only one way. People tend to forget obvious and preferably all the time. Good point. The OP found the obvious way of extending. I wonder what his reasons were to abandon it. You'll have guessed, I'm sure, that I'm not a professional programmer. This was the third rewrite of a program to match candidate groups to examiners on a three day course I run, necessitated on this occasion by a change in the structure of the course. I originally learnt python as I wrote, and some of the early code was ugly and verbose, so once the current rewrite was working I took the opportunity to tidy the code up and document it (yes, I know, but as I said, I'm an amateur). The list concatenation was an itch I couldn't scratch: temp = [] for value in sessexam.values(): temp.extend(value) c_exam = [name for name in set(temp)] #See what I mean about verbose? c_exam.sort() return c_exam Six lines just didn't feel like it ought to be the best way to do something so simple. I liked the attempt below better, but was foolish enough to time it, so that was the end of that. return sorted(list(set(reduce(lambda x, y: x+y, sessexam.values() The current version (below) is a compromise, but I still feel there _ought_ to be a simple one word command to join multiple lists. a = list(set(itertools.chain(*sessexam.values( a.sort() #As I write I'm wondering if I really need it sorted. Hmm... return a You are aware that the above is much more than concatenate a bunch of lists? You want unique values sorting, which are two additional requirements. I'd say 3 lines of code for three requirements is ok, so all = sum(sessexam.values(), []) unique = set(all) sorted_result = sorted(unique) And obviously there are more ways to skin *that* cat, some (as itertools.chain) being less memory intensive: a = sorted(set(itertools.chain(*sessexam.values( It's debatable if this one-liner is really the way to go, but I fail to see how you expect there to be a specialized builtin for this kind of task. Diez -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
On Sun, 27 Jul 2008 16:41:19 +0200, Diez B. Roggisch [EMAIL PROTECTED] wrote: You obviously aren't aware of the pitfalls regarding the mis-use of or and and for this usage. snip example Well, yes, I am (and the way around the problem), but as its never caught me out (so far), I hadn't considered it. Can you tell us what you mean by several names of one object? You mean this? a = range(10) b = a id(a) == id(b) ? Passing references instead of values is an extremely important concept of many languages, without it you would end up copying most of the time. OK. I've obviously been thinking about things the wrong way. In Forth you pass the memory address around, and presumably that's essentially what's happening when you pass a reference. The problem is, I get caught frequently in this situation: a = [1,2,3] def foo(x): do_something_with_x return x ... Then when I call foo(a), a gets changed. It just isn't the effect I expect from changing a local. DaveM -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
Can you tell us what you mean by several names of one object? You mean this? a = range(10) b = a id(a) == id(b) ? Passing references instead of values is an extremely important concept of many languages, without it you would end up copying most of the time. OK. I've obviously been thinking about things the wrong way. In Forth you pass the memory address around, and presumably that's essentially what's happening when you pass a reference. Pretty much, yes. And I for once can say that I've been caught by modifying e.g. stack-locals instead of heap-objects in C++ by accident. The problem is, I get caught frequently in this situation: a = [1,2,3] def foo(x): do_something_with_x return x ... Then when I call foo(a), a gets changed. It just isn't the effect I expect from changing a local. It's the way things work - mutables are mutables. If you want them to be modified, use the module copy. As a rule of thumb, don't return objects you didn't create inside a function from scratch. Which is the exact reasoning for the list.sort method btw - returning None is supposed to make you aware of the in-place modification. Diez -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
DaveM wrote: On Sun, 27 Jul 2008 16:57:14 +0200, Diez B. Roggisch [EMAIL PROTECTED] You'll have guessed, I'm sure, that I'm not a professional programmer. This was the third rewrite of a program to match candidate groups to examiners on a three day course I run, necessitated on this occasion by a change in the structure of the course. I originally learnt python as I wrote, and some of the early code was ugly and verbose, so once the current rewrite was working I took the opportunity to tidy the code up and document it (yes, I know, but as I said, I'm an amateur). The list concatenation was an itch I couldn't scratch: temp = [] for value in sessexam.values(): temp.extend(value) c_exam = [name for name in set(temp)] #See what I mean about verbose? c_exam.sort() return c_exam Six lines just didn't feel like it ought to be the best way to do something so simple. I liked the attempt below better, but was foolish enough to time it, so that was the end of that. return sorted(list(set(reduce(lambda x, y: x+y, sessexam.values() The current version (below) is a compromise, but I still feel there _ought_ to be a simple one word command to join multiple lists. There is, as others have posted, but if you are going to dump the lists into a set, there is no need to concatenate them together first, and it is better not to. Just dump them directly into set. a = list(set(itertools.chain(*sessexam.values( This is a pretty good way of skipping the intermediate long list. Another: a = set() for l in sessexam.values(): a.update(set(l)) If course, if sessexam.values() does not need to be ordered and returns sets instead, the set call in not needed. a.sort() #As I write I'm wondering if I really need it sorted. Hmm... return a If you want all in one line... return sorted(set(itertools.chain(*sessexam.values( There is no virtue to calling list then .sort, since that is what sorted basically does. def sorted(iterable): tem = list(iterable) tem.sort() return tem tjr tjr -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
Gary Herron wrote: A = [1,2,3] B = [4,5,6] C = [7,8,9] A+B+C [1, 2, 3, 4, 5, 6, 7, 8, 9] sum([A,B,C], []) [1, 2, 3, 4, 5, 6, 7, 8, 9] Careful now, this can be very slow. sum uses __add__, not __iadd__, which gives this approach quadratic worst-case runtime. - Anders -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
On Sun, 27 Jul 2008 09:28:28 -0700, Gary Herron [EMAIL PROTECTED] wrote: a = list(set(itertools.chain(*sessexam.values( a.sort() #As I write I'm wondering if I really need it sorted. Hmm... return a Didn't someone already answer that. List addition and sum() both do what you want. A = [1,2,3] B = [4,5,6] C = [7,8,9] A+B+C [1, 2, 3, 4, 5, 6, 7, 8, 9] True, although unsuitable for my circumstance. sum([A,B,C], []) [1, 2, 3, 4, 5, 6, 7, 8, 9] Ah. I had no luck with sum, but I hadn't realised it needed the [] term. I must read about it again. It doesn't get any easier than that. Not only that, but it's exactly what I was after - and fastest, too, although speed isn't really an issue. Thank you. DaveM -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
On Sun, 27 Jul 2008 19:46:32 +0200, Diez B. Roggisch [EMAIL PROTECTED] wrote: As a rule of thumb, don't return objects you didn't create inside a function from scratch. I wish I'd had that advice when I started learning python. It would have saved me no end of grief. DaveM -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
DaveM wrote: On Sun, 27 Jul 2008 19:46:32 +0200, Diez B. Roggisch [EMAIL PROTECTED] wrote: As a rule of thumb, don't return objects you didn't create inside a function from scratch. Unless its job is specifically to get/fetch an object (reference thereto) from someplace the caller cannot or should not access. But then it should probably not mutate the object before returning the reference. I wish I'd had that advice when I started learning python. It would have saved me no end of grief. I wish I had seen this 'rule' before too. -- http://mail.python.org/mailman/listinfo/python-list
Re: Rant (was Re: x*x if x10
Terry Reedy schrieb: DaveM wrote: On Sun, 27 Jul 2008 19:46:32 +0200, Diez B. Roggisch [EMAIL PROTECTED] wrote: As a rule of thumb, don't return objects you didn't create inside a function from scratch. Unless its job is specifically to get/fetch an object (reference thereto) from someplace the caller cannot or should not access. But then it should probably not mutate the object before returning the reference. I maybe should paraphrase don't return objects you passed as arguments from a function. Of course there are exceptions to this rule - but these are few, the canonical being chained function calls like this: class Whatever(object): def do_something(self, arguments): return self Diez -- http://mail.python.org/mailman/listinfo/python-list