It is well acknowledged that Python is one of the most popular languages in current times and many developers choose it since it can be learnt fast and because it provides us many utilities. Besides, Python offers multiple libraries and facilities for development in different areas, such as AI and machine learning, Data analytics, web development, Game development, web scraping, among others.  

However, Python is not only useful but also fun, so now I’m sharing some fun facts you may not know about it:

1. The Zen of Python: If you write `import this` in Python interpreter, you are going to find a poem that mentions Python’s philosophy:  

>>> import this
The Zen of Python, by Tim Peters
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 betten 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!

2. No braces: Python knows, as any developer does, that you don’t use braces to delimit code, but you have to indent the code. If you import braces from the library __future__  you are going to obtain a clever mistake:

>>> from __future__ import braces
File "<stdin>", line 1
SyntaxError: not a chance

 

3.  Antigravity: If you introduce `import antigravity in your Python interpreter, a webpage will open and show you an `antigravity` module comic: https://xkcd.com/353/

Anyway, Python is not only peculiar because of all this but also for offering some peculiarities that are useful for developing applications.

1. Functions can return multiple values: Conversely to other languages, functions in Python can return more than one value as a tuple:

>>> def multiple_values():
        return 7, 'a' 
>>> num, word = multiple_values() 
>>> num 
7

2. *args, **kwars: These arguments are used by convention in the functions when we don’t know how many arguments can be passed. In this way, inside the function we can obtain Non-Keyword Arguments of the argument  *args such as a list of elements or Keyword Arguments of the argument **kwargs, such as a dictionary when the parameters are passed with variables names.
args and kwargs are names by convention, but can be given any other names using ‘*’ an ‘**’ before.

3. Advanced unpacking: Python 3 introduced a new way to assign values of a list to different variables in a tuple: 

>>> a, *rest, b = range(10)
>>> rest
[1, 2, 3, 4, 5, 6, 7, 8]
>>> a
0
>>> b
9

4. Multiple assignments in one statement: In the previous example we observe that Python allows to assign different values to multiple variables in one line. That can be useful if, for example, we want to exchange variable values:

>>> a, b = 1, 2
>>> a, b = b, a
>>> print(a, b)
2 1

5. Else statement in for and while loops: `else` statement is not limited to `if` and `try` but can also be used at the end of a `for`  or `while` block.  If an exception is launched inside the block or a `break` sentence is reached, the code inside the `else`block at the end of the loop won’t be executed.

>>> for i in range(5):
        if i==3:
            print('found')
            break
    else:
        print('not found')
found

6. Chain comparison: The conditions can contain more than one comparison at the same time. There could be a condition that verifies if a value is greater than or less than other at the same time.

>>> 1 < 5 > 2
True

7. Keyword only arguments: Python 3 introduced this new concept that enables to define arguments in a function that can only by specified by the name of the argument and not as positional arguments.  These arguments are delimited by a marker `*` inside the list of arguments.

>>> def func(a, *, option1=False, option2=''):
        pass

In this example, option 1 and option 2 are keyword-only arguments that can’t be called as positional arguments:

>>> func(1,32)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: func() takes 1 positional argument but 2 were given
>>> func(1, option1=True, option2='some')
>>>

8. Positional-only arguments: This is a new functionality in Python 3.8 that indicates the opposite to what I have previously said. In this case, we use the delimiter ‘/’  to indicate the arguments to the left that can only be specified positionally.

>>> def equation(x, y, /, z):
        return x * y + z

In this case, `x` and `y` are arguments that can only be specified positionally.