Hello everyone, sorry about the mistake in the video. @ works as the MATMUL method, not the DOT method. They are similar but not the same.
@theuntitledgoose2 сағат бұрын
what's the dunder method name of this operator?
@thatobject6610Сағат бұрын
__matmul__
@theuntitledgooseСағат бұрын
@@thatobject6610 thanks
@midlander81862 сағат бұрын
Given Python's behavior shown in the video, I thought "b=a.copy()" would just make b a pointer to the "a" memory chunk, but the behavior shown in the video refers to a nested list. If a=[1,2,3] and b=a.copy(), then b[1]=5, say, makes b=[1,5,3], but still a=[1,2,3] (use appropriate "print" statements), so "b" is not just a pointer to variable "a" under b=a.copy(). I honestly don't know what's going on.
@joost007193 сағат бұрын
In C# you just get an exception stating that the collection was modified during the loop.
@Natural_Power3 сағат бұрын
I knew not to do all these things, but it's great to hear why they're bad practises Like I never considered a crash before .close()
@shikanokonokokoshitantan4 сағат бұрын
6th!
@HesderOleh4 сағат бұрын
I know there is a lot of negativity around type(a) == type(b) , but most of the time I do want it to be that strict for comparisons, I want to know are they both cats or both animals so that way I can treat them the same way.
@Indently3 сағат бұрын
I don't understand how isinstance() prevents you from doing that though. Do you mind sharing an example where isinstance() doesn't work for you?
@helloworldprogram585 сағат бұрын
Awesome!!🎉🎉
@RandomytchannelGD5 сағат бұрын
HI
@celestialowl88655 сағат бұрын
The most interesting thing about matmul when not using numpy is that it can be assigned new functionality for a class, effectively acting as an open custom operator.
@ahmadhafez90905 сағат бұрын
I dont think that this operator is equivalent to np.dot() function
@icestormfr5 сағат бұрын
Yep, it's MATMUL (Matrix multiplication) not DOT... If both are 2D matrices dot/matmul/@ give the dame result. In other cases (esp. 3D and higher) they (can) differ
@Indently3 сағат бұрын
Thanks for the correction!
@iestyn1296 сағат бұрын
time to implement this in my classes as an easter egg
@PS3PCDJ10 сағат бұрын
"from X import *" should never be used, if anything "import *" should be used in that case as it will not share the same namespace and will force you to use "module.function()" instead of just "function()"
@dpgwalter11 сағат бұрын
3:04 you can also loop through the list backwards to avoid issues when changing the list as you loop through it. It doesnt sound like it should work but if you play out the logic it will.
@wrxcel14 сағат бұрын
plz upload cat.mp4 to your channel thanks
@exkalybur_dev16 сағат бұрын
excellent
@abstractsage715217 сағат бұрын
Hey, got a concern about the 3rd section, please, consider the following: elements = [] for i in range(50): elements.append('text') print(all([elem is elements[0] for elem in elements]))
@Indently6 сағат бұрын
This code says nothing about nothing, or it just states that all the values in the list comprehension are "Truthy". What do you want to say with this?
@abstractsage71525 сағат бұрын
@@Indently it says that the list consist of the same object (thus we don't create new objects in memory) and in real world you almost never create a list of the same objects, this is just theoretical example. If we modify the code a bit the results are comparable: from timeit import time def new_str(): text = '' for i in range(50): text += f'text{i}' return text def str_append(): text = [] for i in range(50): text.append(f'text{i}') return ''.join(text) new_time = timeit(new_str) print(new_time) str_append_time = timeit(new_str) print(str_append_time) However, for bigger ranges solution with strings is indeed better from memory usage perspective, don't you think so? P.s. I'm not pretending to be a Python expert nor I want to be offensive in any way, peace <3
@officialgreenhero143517 сағат бұрын
Print(“text” * 50)
@stormcall747018 сағат бұрын
i love else
@mustafahaider911520 сағат бұрын
laughs in c#
@manojshettyk20 сағат бұрын
For second one adding [:] will solve the issue...for item in items[:]:.....
@EmreYey21 сағат бұрын
when i first started coding i used to just use a for loop to copy them so this wouldnt happen
@wahbi26.23 сағат бұрын
thank you, the video is helpful
@thirdeye4654Күн бұрын
I was actually told, that fast string concatenation should be done with a StringIO() object. Jesus, I now compared the three methods and it's the worst, double as slow as the list method. I was lied to. So thanks for that input!
@Indently18 сағат бұрын
I heard recently that StringIO was in fact the fastest, I didn't test it myself so I wouldn't be able to comment, but I'll do a bit more research regarding that and possibly post a video soon enough :)
@mikefochtman7164Күн бұрын
Regarding enumerations, one has to remember there's a lot of 'black magic' that happens when the 'for item enumerate(items)' happens. It's creating /using the 'iterable' part of the object and determining the starting and ending points before running the loop. So some things like changing a value is fine, but changing the start or end points by appending or removing is problematic. Using a filter clause is great because then each item is 'tested' against the filter before each new pass through the loop and skipped if fails.
@rohitlearnscodeКүн бұрын
You explain well but the sequence of Keywords isn't right. You might want to consider re-uploading the video and sequencing the keywords from beginner level to advanced level rather than alphabetically.
@pavfrangКүн бұрын
It is very common to remove elements without having to recreate the whole list (for performance reasons)! The common practice for all languages is always to iterate from END to start by index (only). That's all. For a new list, as you already know, a list comprehension with if clause, would be more pythonian (instead of a loop). Other than that, great video!
@user-3bs8jd83jsКүн бұрын
NICE VIDEO !!! (HOPING YOU READ THIS COMMENT AS WELL)
@IndentlyКүн бұрын
Here I am
@Nutzer1402Күн бұрын
Regarding the second example: While creating a copy is more readable and pythonic, and should be preferred in 98% of cases, it is definitely possible to delete items from a list while iterating over it. It might sometimes even be necessary, e.g. if something else holds a reference to that list which you cannot easily update. The main problem is that deleting an item will cause the length of the list to decrease by 1, as well as the index of all subsequent items, while the iterator is unaware of these changes. So `for item in items` from your example will erroneously skip the next item, and `for i in range(len(items))` will raise an `IndexError: list index out of range`. You can circumvent this problem in two different ways. The ugly solution is to use a while loop and manage your index manually: ``` def my_condition(val: int) -> bool: return val < 8 items: List[int] = [x % 10 for x in range(1_000_000)] # numbers 0 to 9, repeating i: int = 0 while i < len(items): if not my_condition(items[i]): del items[i] else: i += 1 ``` The second solution that is still ugly (but a little bit less so) is to iterate over the list in reverse. This way, deleting something will only affect indices that have already been visited: ``` items: List[int] = [x % 10 for x in range(1_000_000)] for i in range(len(items)-1, -1, -1): if not my_condition(items[i]): del items[i] ``` A thing to keep in mind about `items.remove(value)` is that it removes the first (leftmost) occurence of a list entry equal to that value, having to iterate through the list under the hood again to find it, so using `del` in a loop is much more efficient than using `remove` in a loop. Moral of the story: Use something like `items = [x for x in items if my_condition(x)]`, it is also usually much faster than repeatedly deleting from a list.
@DaiShuryoTechnusКүн бұрын
Which IDE is this? Is this PyCharm?
@eliel10268Күн бұрын
Thanks. Are you going to continue this playlist?
@jayandsКүн бұрын
13:55 um, does Python have a spread operator? In JS, if you want to guarantee a new list, you'd use the spread operator: [...target, name].
Пікірлер
Hello everyone, sorry about the mistake in the video. @ works as the MATMUL method, not the DOT method. They are similar but not the same.
what's the dunder method name of this operator?
__matmul__
@@thatobject6610 thanks
Given Python's behavior shown in the video, I thought "b=a.copy()" would just make b a pointer to the "a" memory chunk, but the behavior shown in the video refers to a nested list. If a=[1,2,3] and b=a.copy(), then b[1]=5, say, makes b=[1,5,3], but still a=[1,2,3] (use appropriate "print" statements), so "b" is not just a pointer to variable "a" under b=a.copy(). I honestly don't know what's going on.
In C# you just get an exception stating that the collection was modified during the loop.
I knew not to do all these things, but it's great to hear why they're bad practises Like I never considered a crash before .close()
6th!
I know there is a lot of negativity around type(a) == type(b) , but most of the time I do want it to be that strict for comparisons, I want to know are they both cats or both animals so that way I can treat them the same way.
I don't understand how isinstance() prevents you from doing that though. Do you mind sharing an example where isinstance() doesn't work for you?
Awesome!!🎉🎉
HI
The most interesting thing about matmul when not using numpy is that it can be assigned new functionality for a class, effectively acting as an open custom operator.
I dont think that this operator is equivalent to np.dot() function
Yep, it's MATMUL (Matrix multiplication) not DOT... If both are 2D matrices dot/matmul/@ give the dame result. In other cases (esp. 3D and higher) they (can) differ
Thanks for the correction!
time to implement this in my classes as an easter egg
"from X import *" should never be used, if anything "import *" should be used in that case as it will not share the same namespace and will force you to use "module.function()" instead of just "function()"
3:04 you can also loop through the list backwards to avoid issues when changing the list as you loop through it. It doesnt sound like it should work but if you play out the logic it will.
plz upload cat.mp4 to your channel thanks
excellent
Hey, got a concern about the 3rd section, please, consider the following: elements = [] for i in range(50): elements.append('text') print(all([elem is elements[0] for elem in elements]))
This code says nothing about nothing, or it just states that all the values in the list comprehension are "Truthy". What do you want to say with this?
@@Indently it says that the list consist of the same object (thus we don't create new objects in memory) and in real world you almost never create a list of the same objects, this is just theoretical example. If we modify the code a bit the results are comparable: from timeit import time def new_str(): text = '' for i in range(50): text += f'text{i}' return text def str_append(): text = [] for i in range(50): text.append(f'text{i}') return ''.join(text) new_time = timeit(new_str) print(new_time) str_append_time = timeit(new_str) print(str_append_time) However, for bigger ranges solution with strings is indeed better from memory usage perspective, don't you think so? P.s. I'm not pretending to be a Python expert nor I want to be offensive in any way, peace <3
Print(“text” * 50)
i love else
laughs in c#
For second one adding [:] will solve the issue...for item in items[:]:.....
when i first started coding i used to just use a for loop to copy them so this wouldnt happen
thank you, the video is helpful
I was actually told, that fast string concatenation should be done with a StringIO() object. Jesus, I now compared the three methods and it's the worst, double as slow as the list method. I was lied to. So thanks for that input!
I heard recently that StringIO was in fact the fastest, I didn't test it myself so I wouldn't be able to comment, but I'll do a bit more research regarding that and possibly post a video soon enough :)
Regarding enumerations, one has to remember there's a lot of 'black magic' that happens when the 'for item enumerate(items)' happens. It's creating /using the 'iterable' part of the object and determining the starting and ending points before running the loop. So some things like changing a value is fine, but changing the start or end points by appending or removing is problematic. Using a filter clause is great because then each item is 'tested' against the filter before each new pass through the loop and skipped if fails.
You explain well but the sequence of Keywords isn't right. You might want to consider re-uploading the video and sequencing the keywords from beginner level to advanced level rather than alphabetically.
It is very common to remove elements without having to recreate the whole list (for performance reasons)! The common practice for all languages is always to iterate from END to start by index (only). That's all. For a new list, as you already know, a list comprehension with if clause, would be more pythonian (instead of a loop). Other than that, great video!
NICE VIDEO !!! (HOPING YOU READ THIS COMMENT AS WELL)
Here I am
Regarding the second example: While creating a copy is more readable and pythonic, and should be preferred in 98% of cases, it is definitely possible to delete items from a list while iterating over it. It might sometimes even be necessary, e.g. if something else holds a reference to that list which you cannot easily update. The main problem is that deleting an item will cause the length of the list to decrease by 1, as well as the index of all subsequent items, while the iterator is unaware of these changes. So `for item in items` from your example will erroneously skip the next item, and `for i in range(len(items))` will raise an `IndexError: list index out of range`. You can circumvent this problem in two different ways. The ugly solution is to use a while loop and manage your index manually: ``` def my_condition(val: int) -> bool: return val < 8 items: List[int] = [x % 10 for x in range(1_000_000)] # numbers 0 to 9, repeating i: int = 0 while i < len(items): if not my_condition(items[i]): del items[i] else: i += 1 ``` The second solution that is still ugly (but a little bit less so) is to iterate over the list in reverse. This way, deleting something will only affect indices that have already been visited: ``` items: List[int] = [x % 10 for x in range(1_000_000)] for i in range(len(items)-1, -1, -1): if not my_condition(items[i]): del items[i] ``` A thing to keep in mind about `items.remove(value)` is that it removes the first (leftmost) occurence of a list entry equal to that value, having to iterate through the list under the hood again to find it, so using `del` in a loop is much more efficient than using `remove` in a loop. Moral of the story: Use something like `items = [x for x in items if my_condition(x)]`, it is also usually much faster than repeatedly deleting from a list.
Which IDE is this? Is this PyCharm?
Thanks. Are you going to continue this playlist?
13:55 um, does Python have a spread operator? In JS, if you want to guarantee a new list, you'd use the spread operator: [...target, name].
num: list[int] = [1, 2, 3] c_num: list[int] = num.copy() c_num.append(4) print(f'{id(num)=}') print(f'{id(c_num)=}') print(num) print(c_num)
What is "if name is equal to main"
This was really helpful. Hope you do another one in the future.
print("Hello!" * 50)