AVOID Making 'THIS Stupid Mistake' In Python (It's bad)

preview_player
Показать описание
Avoid making this stupid mistake in Python. It's can be really hard to catch when your projects become bigger, so it's good just to avoid it immediately.

▶ Become job-ready with Python:

▶ Follow me on Instagram:
Рекомендации по теме
Комментарии
Автор

As some of you kindly pointed out, I made a mistake in this video.


Instead of checking:
>> if not items

Please use:
>> if items is None

The reason being that if you happen to pass in an empty list, the if block will still execute with "if not items" because an empty list is a "falsy value". While if you explicity check that the list is None, it will accurately create a new list if a list is not provided.

Indently
Автор

The problem with headlines like this is that when someone makes this mistake in my team it will be impossible to find this specific video when I search for it. I’ve had that problem before, where I searched “Indently import *” and nothing came up cuz the video was title “this is probably the worst mistake you can make”

allo
Автор

The "fixed" implementation seems to be broken too because it does not check for None explicitly, but also replaces an empty list with a new instance. This gives it different and unexpected behavior when passing an empty and populated list, which is not what we want (passing empty lists migh be easily happening in real world software).

Example:

def adder(x, items=None):
if not items:
items = []
items.append(x)
return items

a = []
b = adder(1, a)
c = [1, 2, 3]
d = adder(4, c)
print("a:", a)
print("b:", b)
print("c:", c)
print("d:", d)


This prints out:

a: []
b: [1]
c: [1, 2, 3, 4]
d: [1, 2, 3, 4]

Edit: For some reason did not see the pinned post. Sorry for redundancy.

IlariVallivaara
Автор

Watched this video 6 months ago. Made the exact same mistake 6 months later. Remembered this video and came back to watch how to fix it. Thanks!

chasedunagan
Автор

I have spent the last few days stuck, debugging my code on why the values in my function would still exist, after calling the function again later on. This all makes so much sense, thanks for the video!!!!

anshg
Автор

It is better to use if items is None rather than if not items

minhphamhoang
Автор

I can't believe people are nitpicking calling it a mistake, even going so far as to say that an editor shouldn't even alert the user to it. This feature of Python, while perhaps one that has a purpose, is a pretty heinous violation of the Law of Least Astonishment, and that alone makes it something that should have a spotlight shined on it.

stevenbrown
Автор

This looks more like a stupid feature of pythons implementation of default arguments, rather than a stupid mistake

NickDanger
Автор

I made this mistake yesterday. Surprised to find this video today. I was wondering whether missing parameters default to the value you gave it last time. I had to make a small test program to realise what was happening. VSCode, which warns me about a lot of errors, didn't help with with this one.

eric
Автор

In this example if a user passed an empty list “a” into the function, wouldn’t the returned list be different? It would make sense if you didn’t want to mutate the list passed, but in the case the list is non-empty, it would mutate it. I’d argue you should do if items is not None, not if not items.

Nerdimo
Автор

When typehinting a variable that receives None, it's not better "items: list | None = None"?

daniel_bailo
Автор

Thanks for the explanation, got this warning a couple of times in my code but never understood why.

kruvik
Автор

Actually this feature is very useful. I have made use of this particular feature to implement a recursive algorithm that needs to keep track and update the same list object. It all comes down to your use case of certain feature, and how effectively you use it (that is, if you know what you are doing), therefore I won't consider it a useless feature.

nelmatrix
Автор

Please don't get me wrong, I love python, but I recently realized the only reason I do now is because I have worked in many statically typed languages. As a result I don't think I would ever make this mistake now. all that is to say though that it just goes to show that not because python is easy to learn and write means beginners should learn it. I actually think python is awful for beginners because of easy mistakes like these. After working with typed languages with optionals, the None solution is obvious, but again only if you come from a statically typed, verbose language. I think learning how memory works behind the scenes and how other more traditional languages work is another great way to avoid this. It would be nice if python added language level type checking, but I guess we can't have it all. Ok back to binging your channel now

deathdogg
Автор

in the case above just call add_item and have the function return the list
you cant declare a list then give it two different names which is effectively what you did there, you
did not create two lists you gave the same list declare on the function two names list a and list b

JusticeNDOU
Автор

it should behave this way, when you make list_a and list_b you just pass the string and the default value was set in your definition of your own function, its not a class that pass an instance (self) to make two different list, you write it to work like this . no interpreter should give you any warning, ... . try even two nameless list, and you will get dofferent id
list_a = add_item('a', [])
list_b = add_item('b', [])

the solution is that you pass the list argument that you provide for your function and you yourself gave it a default value, so the interpreter is not giving you any error, cause you, yourself make a single list, if you pass two nameless list when you declaring your list_a and list_b, then every thing just works fine,

xzex
Автор

«If not list» is not that good also. Eg empty list is also evaluates for true.

kamurashev
Автор

It's not stupid mistake if you design it to be, even if you assign it with walrus operator it never be the same list obviously.
list_a = add_item('a', list_a :=[])
list_a = add_item('a', list_a :=[])
list_b = add_item('b', list_a ) unless we use it like this it will consider the list_a as a unique list, and the list_b is not a shallow copy of list _a as we may expect it to be

xzex
Автор

Me at 3:44: what you're gonna do, some guard clause?"
Boy...

Randych
Автор

This video helped my friend, it is most valued one you made

Sinke_