List Comprehensions
The more time I spend with Python, the more I come to like it. The latest in the list (no pun intended) of likable Python-foo is List Comprehensions. What's that? We'll come to it in a bit but now for some background building
(
Read more... )
Comments 13
I can bet, the 'another language' in question is a post-java-era language (ex: Python, Ruby). I think java has opened up the world's eyes on creating languages that allow you to focus on the problem at hand than on programming.
PS: I hate java too, for other reasons of how it is 'mind altering' - on how people tend to forget to tread the path of simply trying to model the real world in a computer program and instead start twisting their own thinking patterns in order to get a working program out... And all I see are decrepit programmers who are the victims of the java-thought-process. They can no longer think straight. In their world, Verbs are extinct.
Reply
Perl and Lisp pre-date Java. Python has been around for longer than you think [#]. I don't understand what you mean in the second sentence about Java allowing you to focus on the problem at hand or other languages stopping you from doing so.
BTW, the post that you linked to is the same as the one I linked to. Not sure if that was intentional.
Reply
mcross = \
lambda ss, row=[]: \
(len(ss) > 1 and \
reduce(lambda x,y: x + y, map(lambda each: mcross(ss[1:], row + [each]), ss[0]),[])) \
or (map(lambda each: row + [each], ss[0])
print mcross([[1,2],[3,4]])
totally warped, but as Horace said "It is when I struggle to be brief that I become obscure"
And yes, I prefer python's map/reduce/filter, because of how nicely it plays into alternative syntaxes
Reply
a) you need to handle the case where ss has zero or one elements since reduce crashes in the former case and fails to invoke the function passed to it as the first parameter in the latter case.
b) you also need to pass around the intermediate result to recursive calls.
c) you replace a function definition with an assignment to an anonymous function. I'm not sure if that's such a bright idea.
d) you replace if/else with and/or, relying on the short-circuit evaluation to do the Right Thing™. That's borderline obfuscation, methinks. I use it too, sometimes, but I wouldn't have used it above.
The List Comprehension version is clearly more brief and less obscure. If you still want to do it the recursive way, there's yield to help you keep the intermediate result around. I started using lambdas and map extensively but quickly gave them up in favour of comprehensions because lambda ( ... )
Reply
mcross = \
lambda ss, row=[]: \
(len(ss) > 1 and \
reduce(lambda x,y: x + y, map(lambda each: mcross(ss[1:], row + [each]), ss[0]),[])) \
or (map(lambda each: row + [each], ss[0])
print mcross([[1,2],[3,4]])
6 non-blank lines, 175 non-space characters. Max line-length: 95
codie.py
def mcross(ss):
if len(ss) == 1:
return [[x] for x in ss[0]]
else:
return [[x] + y for x in ss[0] for y in mcross(ss[1:])]
print mcross([[1,2],[2,3]])
6 non-blank lines, 124 non-space chars. Max line-length: 63
Do I win?
Reply
And I have a weak spot for map/reduce, especially since my original code turns out to be practically identical to the lisp equivalent.
And slowly, I'm training myself to lose the "branch/loop" C-style semantics from my head so that I can start writing GPU style conditional-write pipeline-full code. It requires a lot of unlearning, from what I've realized (see the and/or short-circuiting, for instance).
Reply
Reply
Reply
Reply
Reply
Leave a comment