Overall, this is a nice post. There are two quibbles though. 1). For the most part, "c = collections.Counter()" is almost always better than "c = defaultdict(int)" * Counter only supplies missing values rather than automatically inserting them upon lookup. * The Counter version is much clearer about what it is trying to do. The defaultdict version is cryptic to the uninitiated (understanding it entails knowing that i…
Unfortunately, Counter is not available before 2.7, so for many people it's a bit too early to require it.
A few things to remember while coding in Python
131–140 of 146 posts
Re: A few things to remember while coding in Python
#132Earlier quoted context omitted.
I don't buy this explanation. Actually, this is not a design flaw, and it is not because of internals, or performance. It comes simply from the fact that functions in Python are first-class objects, and not only a piece of code. Why in Common Lisp defaults behave the way one would expect, then? Functions are also first class, but defaults are evaluated at every call.
I don't know CL, but in python function definitions can be executed multiple times... at the top level this happens at module import, so it ends up being only once. But in nested definitions, e.g. def foo(): def bar(): ... return bar foo() == foo() # false Two different function objects are created. If, in the above examle, bar took a pram thelist=[], each call to foo would produce a bar function with a different lis…
When the function represented by the lambda expression is applied to arguments, the arguments and parameters are processed in order from left to right. (...) If optional parameters are specified, then each one is processed as follows. If any unprocessed arguments remain, then the parameter variable var is bound to the next remaining arguments, just as for required parameter. If no arguments remain, however, then the initform part of the parameter specifier is evaluated, and the parameter variable is bound to the resulting value (...).
The CLTL2 specifies that the form representing the default value of optional parameter shall be evaluated every time the parameter is not provided.
Re: A few things to remember while coding in Python
#133halve_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…
impl methods for [T] {
fn filter(f : fn(T)->bool) -> [T] { ... }
fn map(f : fn(T)->U) -> [U] { ... }
}
And then you can call it with syntax like: println(#fmt("%?", [ 1, 2, 3 ].map { |x| x + 3 }));
// prints "[ 4, 5, 6 ]"
The methods are properly scoped, so code that isn't in your module needs to import your methods to use them. That way, you avoid introducing strange action-at-a-distance in your code.Re: A few things to remember while coding in Python
#134Re: A few things to remember while coding in Python
#135Re: A few things to remember while coding in Python
#136Re: A few things to remember while coding in Python
#137Earlier quoted context omitted.
> It's worth explaining why mutable defaults are bad They can also be good. Here's an example from the Reddit discussion, showing how a mutable default can be used to very neatly and cleanly add memorization to a function: def fib(n, m={}): if n not in m: m[n] = 1 if n
Cleverness like this makes you feel warm and fuzzy inside right up to the point where someone decides to actually pass that second argument to your function.
def fib(n, m:"donotusethisparameter"={}):Re: A few things to remember while coding in Python
#138Earlier quoted context omitted.
It is these cases that brought the ternary operator to Python: def f(x=None): x if x is not None else []
Yes, but why? Actually, it's No, because python culture aims to use one way to do thing, the least surprising one. In this case it's: def f(x=None): if x is None: x = []
That said, people still seem to favor your form as the more Pythonic way. Personally, I think that's just because the ternary expression is relatively new.
Re: A few things to remember while coding in Python
#139Overall, this is a nice post. There are two quibbles though. 1). For the most part, "c = collections.Counter()" is almost always better than "c = defaultdict(int)" * Counter only supplies missing values rather than automatically inserting them upon lookup. * The Counter version is much clearer about what it is trying to do. The defaultdict version is cryptic to the uninitiated (understanding it entails knowing that i…
Unfortunately, Counter is not available before 2.7, so for many people it's a bit too early to require it.
Re: A few things to remember while coding in Python
#140Earlier quoted context omitted.
Also Exceptions should be used in "exceptional" circumstances and not as part of normal flow.
One exception (teehee!) to the rule: file operations and other things where atomicity matters. Example code: if not os.path.exists("foo"): os.mkdir("foo") That introduces a race condition. If foo does not exist on the first line but is created by something else on the second line then this will raise an exception. The proper code is: import errno try: os.mkdir("foo") except OSError as exc: if exc.errno != errno.EEXIS…