What Does Pythonic Mean

What does Pythonic mean?

Exploiting the features of the Python language to produce code that is clear, concise and maintainable.

Pythonic means code that doesn't just get the syntax right, but that follows the conventions of the Python community and uses the language in the way it is intended to be used.

This is maybe easiest to explain by negative example, as in the linked article from the other answers. Examples of un-Pythonic code often come from users of other languages, who instead of learning a Python programming patterns such as list comprehensions or generator expressions, attempt to crowbar in patterns more commonly used in C or Java. Loops are particularly common examples of this.

For example, in Java I might use

for(int index=0; index < items.length; index++) {
items[index].performAction();
}

In Python we can try and replicate this using while loops, but it would be cleaner to use:

for item in items:
item.perform_action()

Or, even a generator expression

(item.some_attribute for item in items)

So essentially when someone says something is un-Pythonic, they are saying that the code could be rewritten in a way that is a better fit for Python's coding style.

Typing import this at the command line gives a summary of Python principles. Less well known is that the source code for import this is decidedly, and by design, un-Pythonic! Take a look at it for an example of what not to do.

What do these operators mean (** , ^ , %, //)?

  • **: exponentiation
  • ^: exclusive-or (bitwise)
  • %: modulus
  • //: divide with integral result (discard remainder)

Pythonic vs Unpythonic

My questions is which part/line of the code is costly in the second
version and why? They both "seem to" work the same way and return the
same result in list format.

No they aren't. If in doubt, always profile it, it will give you a picture of the cost for each operation. Just looking at the below O/P does it now tell, what is costly in your second function?

>>> cProfile.run("replace1_word2('foo bar baz')")
313 function calls in 0.000 seconds

Ordered by: standard name

ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <pyshell#216>:1(replace1_word2)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
12 0.000 0.000 0.000 0.000 {len}
286 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
12 0.000 0.000 0.000 0.000 {range}

>>> cProfile.run("replace1_word('foo bar baz')")
27 function calls in 0.000 seconds

Ordered by: standard name

ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <pyshell#220>:1(replace1_word)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
12 0.000 0.000 0.000 0.000 {len}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
12 0.000 0.000 0.000 0.000 {range}

Care to explain what replaces append (or how does the version 1
generate the list)

In Python, function calls have extra overhead. In the former case, the list.append is called multiple times where as in case of list comprehension, the list gets generated as a single expression. So in a sense, there is no equivalent notation for a list comprehension with loop structures. List comprehension is a powerful tool in Python rather than a decorated syntax for loops.

Epilogue

If you ask me to write a function to solve this problem, I would end up something as

>>> from itertools import product
>>> from string import ascii_lowercase
>>> def replace1_word4(word):
words = ('{}'.join([word[:w], word[w+1:]]) for w in range(len(word)))
return [word.format(replace)
for word, replace in product(words, ascii_lowercase)]

What does - mean in Python function definitions?

It's a function annotation.

In more detail, Python 2.x has docstrings, which allow you to attach a metadata string to various types of object. This is amazingly handy, so Python 3 extends the feature by allowing you to attach metadata to functions describing their parameters and return values.

There's no preconceived use case, but the PEP suggests several. One very handy one is to allow you to annotate parameters with their expected types; it would then be easy to write a decorator that verifies the annotations or coerces the arguments to the right type. Another is to allow parameter-specific documentation instead of encoding it into the docstring.



Related Topics



Leave a reply



Submit