Detailed Python: or How to Cross the Border of Knowledge

Do you want your code to look high-quality and concise and speak about you as an experienced developer? Then let's dive a little deeper into the basic knowledge and see how much you can simplify your code, how to make it readable and not lose the desire to return to your work again. Welcome to detailed Python. It's time to get better!

If you started learning Python, watched a dozen training videos, took several free courses, intensive courses and meetups, and are trying to write your first project, then this article will certainly help you. A superficial analysis of Russian-language Python training materials on the Internet suggested that a novice Python developer is rarely shown the beauty and effectiveness of this language. Basic (often non-professional) training involves familiarity with the simplest mechanics, which are often found in other languages. The road will be mastered by the walking one, which means let's strive for more.

In this article you will see:

  • List comprehensions (List Generator)
  • Unpacking items from a list
  • Slicing (Slices or Slices)
  • Some nice Python language tricks
  • Conclusion

List comprehensions (List generator)

In most cases, list generators are used to create a list from a set of values - so as not to resort to more complex constructions via for and append.

Speaking in detail, the list generator can create a collection of values in just one line. Let's see an example:

lst = []
for x in range(10):
    lst.append(x**2)
print (lst)

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

In the example, we took a sequence of numbers from 0 to 9 (our range) and squared each iteration of the loop, after which we wrote the result to the end of the empty list declared above.

So, the result:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Great. And it is difficult to criticize this method because it works, is readable, not cumbersome, right?

Example using a list generator:

print([x**2 for x in range(10)])

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

From four lines to one. Is it beautiful, readable, concise?

Now learn more about the syntax of the generator. In general, it looks like this:

[ expression for iterator in iterable object if condition ]

Yes, the generator can also contain a condition under which the iterated elements will fall into the list. I'll show you an example:

print([x for x in range(20) if x%2==0])

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

Only even numbers were included in the list (if read by condition, these are those that are divisible by 2 without remainder)

Here the efficiency of the generator is even more pronounced. You combine both a loop and a conditional operator in one expression and get an ordered, mutable list at the output.

Now, raise the level:

def some_function(y):
    return (y + 5) / 2

print([some_function(x) for x in range(10)])

[2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0]

You can use an expression as a function argument. This is convenient, and your code will leave a pleasant impression about you.

It is worth mentioning that the generator exists not only for lists, but also for dict and set and is called Dict comprehensions and Set comprehensions, respectively. Their basic syntax is similar. I will show the differences with an example:

dict = {num: num**2 for num in range(5)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

set = {x for x in range(10)}
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

Pay attention to the type of brackets in the list and in these two examples.

Unpacking items from a list

If you need to get a certain element from the collection, then the first and obvious method is to get it by index.

lst = [1,2,3,4] when lst[1] = 2

This method can be used effectively if your collection is immutable, and lst[1] will always contain the value you need. The disadvantage of the approach is the so-called "magic numbers". Imagine that you are reading someone else's code, in which the developer gets the value, as in the example. You won't have any questions: "What is lst[1]? Why 1 and not 2 and not 20?" That's why they call such numbers in parentheses "magic numbers". Appeared out of nowhere, denote something inside. You should learn how to use unpacking.

Python allows you to assign collection values to individual variables. This is effective if the collection is small. Read more in the example:

lst = [1, 2, 3 ]
x, y, z = lst
print(x, y, z)

1 2 3

At the same time, it's worth looking at how to assign multiple values to multiple variables at once, and how to replace variables beautifully.

Multiple assignment

x, y, z = 1, 2, 3

This expression is equivalent to :

x = 1
y = 2
z = 3

But you took 3 lines instead of one. Is it normal if your project will be 50 lines, and if 300 or 800?

Replacing variables.

In order to swap variables, you can do this:

a=10
b=15
_tmp=a 
a=b 
b=_tmp
print(a, b)
15 10

But there is a way to make this record shorter:

a, b = 10, 15
a, b = b, a
print(a, b)

15 10

One of the principles of the Python language states:

Readability counts

So let's be real "pythonists" in our works.

Slicing

Speaking of large collections. What if we need multiple values from a collection? And what if they are needed from the middle or through one? Python provides such a mechanism, which is called Slicing or Slices. The syntax is quite simple:

sequence[start:stop:step]
  • start = index of the element from which the slice starts;
  • stop = index of the element that ends the slice;
  • step = slice step.

Example:

x = [10, 5, 13, 4, 12, 43, 7, 8]
print( x[1:6:2])

[5, 4, 43]

We took every second item in the list from between 1 and 6 indexes. In your work, you will often resort to the help of slices, do not underestimate them.

Slices can be written easier. If the beginning or end of the slice is equivalent to the beginning and end of the list, they can be omitted. It looks like this:

x = [10, 5, 13, 4, 12, 43, 7, 8]
print( x[:3])

[10, 5, 13]

Here we take a slice from 0 to 2 of the index of the element with a step of 1. We didn't specify the beginning or the step, but only the end of the slice. Note that 3 is the index of the final element, but it does not fall into the final list, so the slice will be from 0 to 2 of the index.

Now an example indicating the start:

x = [10, 5, 13, 4, 12, 43, 7, 8]
print( x[3:])

[4, 12, 43, 7, 8]

The slice started with index 3, but in this situation the element with index 3 got into the slice. A similar principle works in range. Just remember that. This way you will eliminate a number of errors in your code.

Some nice Python language tricks

Many people believe that it was fashionable to monitor memory in the era of assembly language programming. Many, but not all. I'll give you a clear example of why sometimes it's worth thinking about which function to use:

import sys

range_list = range(0, 10000)
print(sys.getsizeof(range_list))

48 # bytes

Imagine that a sequence of numbers from 0 to 9999 takes up only 48 bytes.

And here is an example with the same sequence:

import sys

real_list = [x for x in range(0, 10000)]
print(sys.getsizeof(real_list))

87616 # bytes

Two identical sequences from 0 to 9999. They occupy memory with a difference of almost 2000 times. And if the program contains 100 such lists?

The fact is that range only pretends to be a list, behaves like a list, but in fact, the range function returns a class and, of course, loads less memory.

And finally, a small focus on the number of repetitions of the value in the collection (a favorite task in various tutorials and courses):

from collections import Counter
print(Counter('abracadabra').most_common(1))

[('a', 5)]

You can use a list instead of a string:

from collections import Counter
lst = [2, 2, 2, 5, 5, 6, 7, 6, 9, 2, 4, 8, 5]
print(Counter(lst).most_common(1))

[(2, 4)]

The argument in most_common specifies the number of repeatable elements that need to be counted:

from collections import Counter
print(Counter('abracadabra').most_common(3))

[('a', 5), ('b', 2), ('r', 2)]

It is worth noting that for the mechanisms described in the article to work correctly, it is necessary to have a full understanding of lists, dictionaries, sets, and tuples. These types of data are very insidious and have important differences that are worth paying attention to.

Conclusion

Deeper immersion in the technology being studied always brings its own result. After reading this material, you will get the opportunity to distinguish the code of a beginner (or lazy) from the code of a developer who loves his work, immerses himself in it, tries to do not only for himself but also for others. You will want to establish contact with such people, make a joint project or invite them to work. Writing code is like drawing: all paints are the same color, but some get a house with a triangular roof, while others have magnificent landscapes. The question is effort.

Put on Heart if you liked it and you learned something new!

You can also follow ME to receive notifications about new interesting articles.

FAQ

I am a beginner, how should I learn Python?

Look into the following series:

Can we cooperate with you?

If you have interesting projects and you need a python (web)developer, then you can contact me by mail or discord and LinkedIn for cooperation

Connect to me on


To beat depression, try to just quit #programming 🤪

— Vadim Kolobanov (@decodesperato)

21