📜 ⬆️ ⬇️

5 common mistakes novice programmers in Python

In the first days of our work as a Python programmer, we all encounter different types of bugs in our code, which after several painful hours in StackOverflow turn out to be not a bug, but features of Python. Below are 5 of the most common mistakes that most novice Python programmers make. Let's find out a little about them in order to save a few hours by asking questions on pages and in groups on Facebook.

1. Copy dictionaries or lists


When you need to make a copy of a dictionary or list, it is not enough just to use an assignment operator.

Wrong:

>>> dict_a = {"name": "John", "address":"221B Baker street"} >>> dict_b = dict_a 

Now, if you change or update dict_b, then dict_a will also be changed - all thanks to the assignment operator. Using this operator, you are trying to say that dict_b will point to the same object as dict_a.
')
 >>> dict_b["age"] = 26 >>> dict_b {'address': '221B Baker street', 'name': 'John', 'age': 26} >>> dict_a {'address': '221B Baker street', 'name': 'John', 'age': 26} >>> 

Correct: use copy () or deepcopy () methods.

 >>> dict_c = dict_b.copy() >>> dict_c["location"] = "somewhere" >>> dict_c {'address': '221B Baker street', 'name': 'John', 'age': 26, 'location': 'somewhere'} >>> dict_b {'address': '221B Baker street', 'name': 'John', 'age': 26} >>> dict_a {'address': '221B Baker street', 'name': 'John', 'age': 26} >>> 

See the difference between copy and deepcopy.

2. Keys dictionaries


Let's try adding values ​​to the dictionary:

 >>> dict_a = dict() >>> dict_a {} >>> dict_a[1] = "apple" >>> dict_a[True] = "mango" >>> dict_a[2] = "melon" 

If we try to display the dictionary on the screen, what will we see?

 >>> dict_a {1: 'mango', 2: 'melon'} 

What happened, where is the key true?

It must be remembered that the class Boolean is inherited from Integer (integers). And an integer equivalent to True is 1; the equivalent of False is 0. Hence, the value for key 1 is simply rewritten.

 >>> isinstance(True, int) True >>> isinstance(False, int) True >>> True == 1 True >>> False == 0 True 

3. Updating lists or dictionaries


Suppose you want to add an item to the list.

 >>> list_a = [1,2,3,4,5] >>> list_a = list_a.append(6) >>> list_a >>> # prints nothing 

Or trying to update the dictionary.

 >>> dict_a = {"a" : "b"} >>> dict_a = dict_a.update({"c" : "d"}) >>> dict_a >>> # prints nothing 

And now let's try to sort the list.

 >>> list_b = [2,5,3,1,7] >>> list_b = list_b.sort() >>> list_b >>> # prints nothing 

Why nothing is displayed, what are we doing wrong?

Most container methods (such as sort, update, append, add, etc.) are optimized for performance purposes — and avoid unnecessary creation of separate copies.

Do not attempt to assign the return value of such methods to a variable.

Right:

 >>> list_a = [1,2,3,4,5] >>> list_a.append(6) >>> dict_a = {"a" : "b"} >>> dict_a.update({"c" : "d"}) >>> dict_a {'c': 'd', 'a': 'b'} >>> list_a.sort() >>> list_a [1, 2, 3, 4, 5, 6] 

4. Interned lines


In some cases, Python tries to reuse existing immutable objects. String interning is one such case.

 >>> a = "gmail" >>> b = "gmail" >>> a is b True 

Here we tried to create two different objects - strings. But when we checked them for equivalence, it turned out that they completely coincide. This is due to the fact that Python did not create another object b, but made b pointing to the first value of "gmail".
All strings of length 1 are interned. Lines that contain something other than ASCII characters, numbers, and the underscore character will not be interned.
Let's check.

 >>> a = "@gmail" >>> b = "@gmail" >>> a is b False 

You also need to remember that == is different from the is operator. The == operator checks whether the values ​​are equivalent or not, whereas the is operator checks whether both variables refer to the same object.

 >>> a = "@gmail" >>> b = "@gmail" >>> a is b False >>> a == b True 

So keep this in mind when using immutable strings or the == and is operators.

5. Arguments by default are evaluated once.


Consider an example:

 def func(a, lst=[]): lst.append(a) return lst print(func(1)) print(func(2)) 

What do you think will be displayed after two prints?

Let's run the code.

 >>> def func(a, lst=[]): ... lst.append(a) ... return lst ... >>> print(func(1)) [1] >>> print(func(2)) [1, 2] 

Why in the second case is displayed [1, 2]? Shouldn't it be just [2]?

So, the catch is that the arguments are calculated by default only once. When you first called the function - func (1) - the list was evaluated and realized that it was empty. So, you can add 1 to it. But in the second call, func (2), there is already one element in the list, so [1, 2] is displayed.

Bonus: Do not mix spaces and tabs. Just do not.

Source: https://habr.com/ru/post/458902/


All Articles