Tutorial :“”.join(reversed(val)) vs val[::-1]…which is pythonic?



Question:

So according to the Zen of Python ... Explicit is better than implicit...Sparse is better than dense...Readability counts...but then again Flat is better than nested...so then which is pythonic?

val = "which is pythonic?"  print("".join(reversed(val)))  

or

print(val[::-1])  

I'm just a Java programmer learning Python so I find this pythonic stuff interesting since there is no analog in the Java world AFAIK.


Solution:1

My wife Anna has nicknamed x[::-1] "the Martian Smiley" -- I mostly bow to her (and her long experience in training &c, and studies in human psychology &c), when it comes to judging what's easy and natural for most people, and she absolutely loves the martial smiley. "Just walk it backwards" -- how much more direct, and high-abstraction, than the detailed specification of "reverse it and then join it back"!

Also, python -mtimeit is often a good judge of what's Pythonic: top Pythonistas, over the years, have of course tended to optimize what they most often needed and used, so a very substantial performance difference tells you what "goes with the grain" of the language and its top practitioners. And by that score, the martian smiley beats the detailed spec hands-down...:

$ python -mtimeit '"".join(reversed("hello there!"))'  100000 loops, best of 3: 4.06 usec per loop  $ python -mtimeit '"hello there!"[::-1]'  1000000 loops, best of 3: 0.392 usec per loop  

order-of-magnitude performance differences just don't leave that much room for doubt!-)


Solution:2

The second one (in my opinion) is more Pythonic as it is simpler, shorter, and clearer.

For more info on what is Pythonic I would recommend The Zen of Python:

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than right now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

In my opinion your second example satisfies these tenets:

Beautiful is better than ugly.
Simple is better than complex.
Sparse is better than dense.
Readability counts.


Solution:3

With a string, as you have, I would go with the first option, since it makes it clear that the result you want is a string. For a list or other iterable/slicable, I'd go with the second.

An added benefit of the first form is it will work if val is not actually a string, but some other iterable of characters (e.g. a generator of some kind). In some cases, this makes a big difference.


Solution:4

First, if you are a beginner, don't worry what is more pythonic or not. This smell language wars, and you will eventually find your own opinion anyway. Just use the way you think is more readable/simpler for you and you will find the light, I think.

That said, I agree with Alex's excellent answer (as he is always right) and I would add an additional comment why you should prefer the second method - the first will only work correctly if val is a string.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »