Earlier quoted context omitted.
Functions (methods) are first class objects also in Ruby: methods are instances of the class Method, while Procs are a lightweight alternative. Default arguments in Ruby are not mutable in any kind of function object, be it a lambda proc, a regular proc, or a method. You can use a mutable default argument as an ersatz static variable, e.g. for memoization.
> Default arguments in Ruby are not mutable in any kind of function object Maybe I misunderstood you, but they are perfectly mutable: class A attr_accessor :a def initialize @a = [] end def b x = a x # obj.b # => [1] obj.b # => [1, 1] obj.a # => [1, 1] If you mean "inline default arguments are not mutable", that's not true either. What is true is that the default argument is evaluated when the function is called, not…
A few things to remember while coding in Python
81–90 of 146 posts
Re: A few things to remember while coding in Python
#82Earlier quoted context omitted.
My lisp is a bit rusty, but it looks like what you're doing there is returning a function which gets redefined every time you reuse the function. The equivalent Python would be something like this: def function(): x = 3 def internal(x, foo=[]): foo.append([7]) foo.append(x) return foo return internal(x) print function() print function() Which does what you would expect: [[7], 3] [[7], 3]
No. In my example the function is created only once, and called twice.
Re: A few things to remember while coding in Python
#83The recommendation on `iteritems` had better be generalized to include `iterkeys`, `itervalues`, and other opportunities for using iterators rather than building lists. A note that the 'iter...' versions are removed in Python 3 (because iterator behaviour becomes the default) would be appropriate here.
In relation to collections, itertools is a great module to get familiarized with. I import * from this module. I consider functions there as if they were builtins.
"Conditional assignment" is a weak and misleading name. "Conditional expressions" is more descriptive. There is no assignment in
print "yes" if some_condition else "no"
as the article acknowledges later.Using Ellipsis for getting all items is a violation of the Only One Way To Do It principle. The standard notation is [:].
I commend the good intentions of the writer, but I'm surprised that this article got 144 upvotes in HN.
Re: A few things to remember while coding in Python
#84Re: A few things to remember while coding in Python
#85Earlier quoted context omitted.
Trailing commas are really easy to miss. When reading this line of code, I did not notice it immediately; I originally assumed that varname was being assigned a list. This sort of code would be very confusing when I'm just quickly reading through a procedure trying to find the potential bug.
Agreed. It could be written much more clearly in my opinion like this: [varname] = [x for x in l if predicate_with_single_truth_value(x)]
Re: A few things to remember while coding in Python
#86Earlier quoted context omitted.
But 'def' doesn't have to work that way. Consider, in CL: > (defvar *fn* (let ((x 3)) (lambda (&optional (y (list nil x))) (push 7 (car y)) ; modifies the list y))) *FN* > (funcall *fn*) ((7) 3) > (funcall *fn*) ((7) 3) From this example you can see two things. First, the binding of 'x' is closed over when the lambda expression is evaluated. And second, the expression that provides the default value of 'y' is evaluat…
My lisp is a bit rusty, but it looks like what you're doing there is returning a function which gets redefined every time you reuse the function. The equivalent Python would be something like this: def function(): x = 3 def internal(x, foo=[]): foo.append([7]) foo.append(x) return foo return internal(x) print function() print function() Which does what you would expect: [[7], 3] [[7], 3]
Re: A few things to remember while coding in Python
#87halve_evens_only = lambda nums: map(lambda i: i/2, filter(lambda i: not i%2, nums)) I still find it rather silly that python doesn't supper a nice list map/filter; it could be so much nicer nums.filter(lambda i: i%2 == 0).map(lambda i: i/2) If they did, even including the annoyingly long-to-type "lambda". List comprehensions are cool and all, but do not really scale visually (i.e. get rather messy) when you have more…
(lambda i: i%2 == 0).filter((lambda i: i/2).map(nums))
makes (marginally) more sense. But I like filter and lambda alright as they are. I agree Python's inconsistency in this is a bit unfortunate, but I haven't had much of a problem with the runtime errors you mention.
Re: A few things to remember while coding in Python
#88Earlier quoted context omitted.
I am but an egg, but isn't this the same but shorter? def f(L=None): L = L or []
It might work the same depending on your use of it but it's not the same. In that instance L will become a blank list if it is equal to None, zero, or a zero length string. There are many cases where this wouldn't affect anything, but there can also be instances where that will cause you to define L as a blank list when you really wanted to keep L's value. I think it's always better to be explicit and test for the va…
These are the little assumptions that keep blowing off my feet. Thanks.
Re: A few things to remember while coding in Python
#89Earlier quoted context omitted.
It's most certainly not a mistake; Python 3 would probably have fixed it, if it were. It is an (admittedly, strange) side effect of the way 'def' works.
But 'def' doesn't have to work that way. Consider, in CL: > (defvar *fn* (let ((x 3)) (lambda (&optional (y (list nil x))) (push 7 (car y)) ; modifies the list y))) *FN* > (funcall *fn*) ((7) 3) > (funcall *fn*) ((7) 3) From this example you can see two things. First, the binding of 'x' is closed over when the lambda expression is evaluated. And second, the expression that provides the default value of 'y' is evaluat…
fn = lambda y=[y]: y.push(7); return y
if you accept the ; to separate statements, as the lambda in python is syntactically only allowed to contain one statement.(The introduction of the variable x into the example is not important for the behavior of default arguments, however, it is important for a separate issue. I've stripped it out here.)
Re: A few things to remember while coding in Python
#90Earlier quoted context omitted.
No. In my example the function is created only once, and called twice.
What's that lambda thingo in the middle then? Pretty sure that's another function, redefined every time your function is called.