On Thu, May 30, 2013 at 9:34 AM, Ma Xiaojun <damage3...@gmail.com> wrote: > > On Thu, May 30, 2013 at 10:49 AM, rusi <rustompm...@gmail.com> wrote: > > Ha,Ha! The join method is one of the (for me) ugly features of python. > > You can sweep it under the carpet with a one-line join function and > > then write clean and pretty code: > > > > #joinwith > > def joinw(l,sep): return sep.join(l) > > > > def mktable(m,n): > > return [[(j,i,i*j) for i in range(1,m+1)] for j in range(1,n+1)] > > > > def prettyrow(r): > > return joinw(['%d*%d=%d' % ele for ele in r],'\t') > > > > def prettytable(t): > > return joinw([prettyrow(r) for r in t],'\n') > > Wait a minute! Isn't the most nature way of doing/thinking "generating > 9x9 multiplication table" two nested loop?
Thats like saying that the most natur(al) way of using a car is to attach a horse to it. Sure if all you've seen are horse-carriages then a horseless carriage will seem nonsensical. Once you get used to horseless carriages the horsed ones would seem quite a nuisance [global warming aside!!] The only problem with this analogy is that you have to imagine the world of horse/horseless 'cars' in 1900 and not 2013. Likewise in the world of programming, 90% of programmers think imperative/OO programming is natural while functional programming is strange. Just wait 10 years and see if things are not drastically different! > > I understand that using "join", we don't need to worry about "one > element doesn't need white space" issue. And that's it. More evidence of the above! join like list-comprehensions are tools for functional programming and not merely ways of writing loops in short. The key difference between the two is seen not in the code you write but in the natural language (English) you use to describe it: > Wait a minute! Isn't the most nature way of doing/thinking "generating > 9x9 multiplication table" two nested loop? You associate the primal (f)act of thinking about programming with *doing* the generating. By contrast the functional programmer thinks about what *is* the result. Please also note the difference in emphasis in your code and mine. Rewriting to make it more obvious: # The main multiplication table building function def multtable(m,n): return [[(j,i,i*j) for i in range(1,m+1)] for j in range(1,n+1)] # The 'icing' to get it into the shape you want def joinw(l,sep): return sep.join(l) def prettytable(t): return joinw([joinw(['%d*%d=%d' % ele for ele in r],'\t') for r in t],'\n') The call that puts them together: >>> print prettytable(multtable(6,7)) The nice thing about the last is that it separates three things: 1. Computing the actual table 2. The string form of that table that looks the way we want 3. Printing that string And I can see each of these separately: In [2]: multtable(2,3) Out[2]: [[(1, 1, 1), (1, 2, 2)], [(2, 1, 2), (2, 2, 4)], [(3, 1, 3), (3, 2, 6)]] In [3]: prettytable(_) Out[3]: '1*1=1\t1*2=2\n2*1=2\t2*2=4\n3*1=3\t3*2=6' In [4]: print _ 1*1=1 1*2=2 2*1=2 2*2=4 3*1=3 3*2=6 ------------------- I would be pleasantly surprised if the double nested loop you think natural, allowed for such a modular separation! -- http://mail.python.org/mailman/listinfo/python-list