Python's sharpest corner is ... plus equals? (+=)

Поделиться
HTML-код
  • Опубликовано: 16 июн 2024
  • If you thought x+=y means x=x+y you'd be wrong!
    Python's plus equals augmented assignment syntax is more complex than many people realize. Let's take a look.
    (Sorry for the dark purple again! I've changed it in my ide to pink for the future!)
    ― mCoding with James Murphy (mcoding.io)
    Source code: github.com/mCodingLLC/VideosS...
    Docs for iadd: docs.python.org/3/reference/d...
    SUPPORT ME ⭐
    ---------------------------------------------------
    Patreon: / mcoding
    Paypal: www.paypal.com/donate/?hosted...
    Other donations: mcoding.io/donate
    BE ACTIVE IN MY COMMUNITY 😄
    ---------------------------------------------------
    Discord: / discord
    Github: github.com/mCodingLLC/
    Reddit: / mcoding
    Facebook: / james.mcoding
  • НаукаНаука

Комментарии • 560

  • @ArsenicDrone
    @ArsenicDrone 2 года назад +177

    More broadly, the choice in Python not to have a prominent division between things that are pointers (still can be changed when you send them off somewhere else) and things that are not pointers (are copies when they're elsewhere) is a very easy place to get tripped up, especially for those who are used to stricter languages.

    • @tongpoo8985
      @tongpoo8985 Год назад +21

      Definitely my least favorite thing about python

    • @JohnChaussard
      @JohnChaussard Год назад +3

      i believe everything is a pointer in python, and nothing acts like a copy, making it more easy to understand the behavior of a program… In the last example given, L was indeed a pointer, but the += reassigned the value of the pointer to a new place, and therefore, the change couldn’t be seen from the main function… The problem comes from the fact that, if not well documented, it is difficult to know what will be the behavior of basic functions (addition, +=, …) on objects.

    • @daskadse769
      @daskadse769 Год назад +17

      @@JohnChaussard While yes, everything in python is an object (and thus, a pointer), the immutability of some things make them behave more like values. But as you are saying, when specific operations are ambiguous over whether they operate on the pointer or the object, that's confusing at best (and bad language design at worst). This is all over python (see descriptors for example), and while it does enable some dark magic, I'd personally argue it does not make the language more usable.

  • @blakewalsh9489
    @blakewalsh9489 3 года назад +648

    I don't feel bad for having a severe distrust of += in python now, nice to have a clearer understanding of it though.

    • @deidyomega
      @deidyomega 3 года назад +27

      += is fine, just always treat everything like a primitive and you'll be safe. In his example, if he would have returned the l var ([4,5,6]), he would have gotten the expected results.

    • @devanshgarg31
      @devanshgarg31 2 года назад +1

      Yess

    • @insidiousmaximus
      @insidiousmaximus 2 года назад +28

      @@SquidBeats there is no spoon

    • @aleongh
      @aleongh 2 года назад +2

      @@SquidBeats k

    • @DendrocnideMoroides
      @DendrocnideMoroides 2 года назад +5

      @@SquidBeats how do you know that Hell is real? have you seen it, if so how can I see it?

  • @pharoah327
    @pharoah327 Год назад +14

    There's a principal in language design known as "least astonishment". The idea is to make a feature work in the least astonishing (aka least unexpected) way. So when you create a feature, make it work in the way most developers would expect it to work. I don't think Python got the memo on this

  • @Mutual_Information
    @Mutual_Information 3 года назад +375

    I’ve been writing Python code for a long time.. and a lot for my own videos, but I learn something new with each of these lessons! I think I need to hunker down and make sure I watch all of them.

    • @mCoding
      @mCoding  3 года назад +39

      Thanks for the support !

    • @doltramir
      @doltramir 3 года назад +10

      Same here. I'm writing python for around 7 or 8 years now. And this is the first time i saw this problem. This is because i never used python in a way that will show this behaviour (because tuple is strictly immutable, and because i use list.append and list.extend instead of adding it). But i immediately got what will happen in this code. Just didn't happen to me ever.

    • @SquidBeats
      @SquidBeats 2 года назад

      Jesus Christ is God and is the only way. Hell is real whether you believe it or not.

  • @MitchellD249
    @MitchellD249 3 года назад +446

    "Slap that like button an odd number of times"
    *slaps like, then dislike, then like 2 more times*
    What now mCoding?

    • @mCoding
      @mCoding  3 года назад +196

      You got me.

    • @Pacvalham
      @Pacvalham 3 года назад +28

      How about "toggle the like button an odd number of times"?

    • @tahaan99
      @tahaan99 3 года назад +12

      @@Pacvalham But that wouls still not have the desireable effect if the person has followed the instructions an odd number of times before.

    • @mrpedrobraga
      @mrpedrobraga 3 года назад +16

      @@mCoding
      while ( not like_button.is_activated() ):
      toggle_like_or_dislike()
      Runtime dynamic check.

    • @relvisdsouza3541
      @relvisdsouza3541 3 года назад +2

      @@mrpedrobraga you went full nerd

  • @usharma1624
    @usharma1624 3 года назад +750

    Developer1: "+= has a bug, what should we do?"
    Developer2: "Just fix it"
    Developer1: "We don't have time, we must do something else"
    Developer2: "Tell everyone that this is a feature, not a bug"
    Developer1: "... Great Idea"
    Great video! Learnt a lot form this!

    • @mCoding
      @mCoding  3 года назад +88

      Exactly!

    • @vbregier
      @vbregier 3 года назад +45

      I would say this is broken semantics, more than a bug.
      An operator should not have two very distinct semantics (either modify the object binded to the variable, or rebind the variable to a new object).
      There should be two distinct operators / functions, for each semantic.

    • @adrulb
      @adrulb 3 года назад +15

      @@vbregier I wouldn't say it's broken, it's just different contexts: in all cases it means "add this to that", if I said I wanted to "add a character to a string" it's obvious what my intention is: take the string, append the character to the end and wríte that back to the variable. If I said I wanted to "add a number to a number" it's also obvious what I want to do. Same goes for "adding a string to a list (of strings)".

    • @vbregier
      @vbregier 3 года назад +32

      @@adrulb The semantics of an operator should not depend on the context.
      Different semantics need different operators / methods.
      You are not seeing it because the word "add" itself has this problem : do you mean generate a new value, or modify the value you add to ?
      Mutability of objects is crucial in programming, it must be clear which objects are modified and which are not for a given operation.

    • @dtkedtyjrtyj
      @dtkedtyjrtyj 3 года назад +23

      @@vbregier Yes, the problem is that concatenation is not the same as addition. Not having a separate concatenation operator is one of the few flaws in Python.

  • @aragonnetje
    @aragonnetje 2 года назад +26

    Personally the "BadList" implementation makes more sense to me. For appending things to a list, we have append and extend. a += b should be effectively the same as a = a + b

    • @mintypotato6205
      @mintypotato6205 Год назад +5

      in python 2, this was the implementation, and if you iteratively created a large list, it would use SEVERAL GBs of memory (think 125GB for a 500 000 element (500 KB+) list).
      My friend came across this when doing a file handling program and crashed python - It can be done in less than 10 lines of code (and it is difficult to fix).

    • @aragonnetje
      @aragonnetje Год назад +2

      @@mintypotato6205 wouldn't it be instantly fixable with .extend() though?

    • @Redhotsmasher
      @Redhotsmasher Год назад

      @@mintypotato6205 Difficult to fix how? Did Python 2 lists not have the .append() method or something?

  • @ManuelBTC21
    @ManuelBTC21 3 года назад +42

    7:30 Rarely comes up indeed. Can't recall ever encountering this specific issue after 10+ years of programming in Python. In any case, mutability is the root cause of this and should be handled with care.

    • @mCoding
      @mCoding  3 года назад +7

      It has only come up once in my programming career!

  • @VojtechMach
    @VojtechMach 3 года назад +87

    Man, you are great, this is exactly the content I was missing on YT. Advanced stuff, straight to the point. Keep up the good job.

    • @mCoding
      @mCoding  3 года назад +4

      Thank you for the kind words!

  • @HaBBiSiFy
    @HaBBiSiFy 2 года назад +4

    Great topic. I had a hard time figuring this out a year ago when I was working with PyTorch - it turned out it was imperative to use x = x + foo instead of x += foo in many places since they are, counterintuitively, not the same expression... This video shed some light to the matter. Thank you!

  • @Ovicron
    @Ovicron 3 года назад +112

    I didn't even know about the __iadd__ method 😅.
    Also, The audio is so good now.

    • @mCoding
      @mCoding  3 года назад +18

      Thank you so much, I'm doing everything I can to up the audio quality

    • @Sirjosephcharles
      @Sirjosephcharles 3 года назад +1

      iAdd is part of @mCoding user created class. This doesn’t mean it’s native method, correct?

    • @Ovicron
      @Ovicron 3 года назад +9

      @@Sirjosephcharles the dunder iadd method is a magic method, it is used to overload the += operator.

  • @griof
    @griof 3 года назад +14

    Another sharp corner: function default mutable parameters. I think most of us have fallen in this bug... I mean this _feature_

  • @davidharmeyer3093
    @davidharmeyer3093 2 года назад +9

    Just watched the entire video and honestly, I still feel like it's even more surprising that ++ doesn't exist

  • @dsenese
    @dsenese 3 года назад +41

    The mutable integer id really blow my mind! I learn so much with your videos. One suggestion: you could put the python docs that you are refering to on the description :) Thanks!

    • @mCoding
      @mCoding  3 года назад +7

      docs.python.org/3/reference/datamodel.html#object.__iadd__

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 3 года назад +8

      Unfortunately, RUclips screws up the formatting of that URL ...

  • @AndyChamberlainMusic
    @AndyChamberlainMusic 3 года назад +51

    "as always, slap that like button an odd number of times"
    me, an intellectual: watches the video an even number of times

  • @Treebark1313
    @Treebark1313 3 года назад +4

    This video is fantastic. I've been using Python for years and noticed some weirdness with these operators but never dug into it. Thanks for producing such high quality educational content!

    • @mCoding
      @mCoding  3 года назад +1

      You're very welcome!

  • @Tal__Shachar
    @Tal__Shachar 3 года назад +28

    Dude. Do you sleep?
    Your content is of impeccable quality and is just shooting into my notif box. How do you make so many freaking good videos I love your channel ahhh

    • @mCoding
      @mCoding  3 года назад +9

      The bags under my eyes you might think that I don't ever sleep! But rest assured, I get plenty! Thank you for the support

  • @franferri
    @franferri 2 года назад

    You are one of the best perk teachers around the youtube block. Enjoying your vids a lot.

    • @mCoding
      @mCoding  2 года назад

      Thank for the praise!

  • @andersonklein3587
    @andersonklein3587 2 года назад +5

    The more I learn about other languages, the more I understand why people still write in C. It's the only language to date where things never not made sense to me.
    You pass references, pointers, you can modify any piece of memory anywhere in the stack, or allocate heap, it's perfectly transparent. When working with Python, that I do often use and is great for some stuff, whenever I'm working with a new function or circumstance I never know what to expect without reading the full documentation on how it works under the hood.

    • @jurjenbos228
      @jurjenbos228 Год назад +1

      You know what they say: C combines the power of assembly language with the flexibility of assembly language.

  • @MrRocksW
    @MrRocksW 3 года назад

    Your channel is great really enjoying your videos. I like watching intermediate/ advanced videos on python.

    • @mCoding
      @mCoding  3 года назад

      Glad you like them!

  • @vsolyomi
    @vsolyomi 3 года назад +88

    A talk on persistent data structures would be awesome... You don't seem that much a functional programming enthusiast, but I think it might be great to discuss limitations of standard data types in relation to copying and mutability and how it can be circumvented.

    • @mCoding
      @mCoding  3 года назад +39

      Python supports many program paradigms, including functional. This would be a great idea for future!

    • @ross825
      @ross825 2 года назад +3

      I've been playing with pyrsistent and I have fallen in love with using evolvers instead of mutable mappings and arrays.

  • @brightsideofmaths
    @brightsideofmaths 3 года назад

    Very nice channel! Keep up the good work!

  • @AbelShields
    @AbelShields 3 года назад +10

    Ahh Python, reminds me of good old True = False, and messing around with the cached small integer objects, changing their actual ctypes value. It's definitely good for quick prototyping but there are so many quirks... Looking forward to watching more!

    • @mCoding
      @mCoding  3 года назад +4

      Good times!

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 3 года назад +5

      Seems “True” and “False” could indeed be (re)assigned in Python 2, but they are reserved words in Python 3. Not before time ...

  • @cynical5062
    @cynical5062 Год назад +1

    3:27 "I can't change a 1 into a 2"
    this is mostly true, but with ctypes:
    import ctypes
    ctypes.c_longlong.from_address(id(1)+24).value = 2
    print(1)
    this code prints 2
    until you change the value again, or restart python, 1 is 2

  • @infinitelyexplosive4131
    @infinitelyexplosive4131 3 года назад +1

    You're very good at presenting technical topics.

    • @mCoding
      @mCoding  3 года назад

      It's a gift!

  • @aronhegedus
    @aronhegedus 2 года назад +2

    interesting to see what COULD go wrong. I think the lesson is: don't write a class that inherits from list, and keep += for basic loops, and use .extend() for lists instead

  • @rosiefay7283
    @rosiefay7283 3 года назад +9

    2:38 Argh. This is the sort of bug you can get when you use C macros which have parameters. And yet you get bugs like that in python even if you write something which looks safe.

  • @microwavecoffee
    @microwavecoffee 3 года назад +3

    These videos are great. Hope your channel gets big.

    • @mCoding
      @mCoding  3 года назад +1

      I hope so too! Thanks for your support!

  • @liammail9884
    @liammail9884 3 года назад +1

    Pretty sure I just watched an 8-min Jedi mind trick designed to increase James' subscription count. Fair enough. Subscribed because it helps James and it feels good.

    • @mCoding
      @mCoding  3 года назад

      I appreciate it!

  • @CrapE_DM
    @CrapE_DM 3 года назад +11

    Yeah, the data model for __iadd__ is broken in my opinion. Instead of usually returning `self`, it shouldn't return anything. Then, instead of the += turning into `x = x.__iadd__(y)`, it should just be `x.__iadd__(y)`. The whole point of the in-place overloads is to modify yourself instead of returning a new object, as the base versions of the operators do. Not only would this help people understand the point better, it would remove your tuple bug.

    • @mCoding
      @mCoding  3 года назад +3

      yeah this really confused me at first. I think the part that got me was the reassigning the variable after doing the iadd, which other languages typically don't

  • @tudor1899
    @tudor1899 Месяц назад

    Always top notch stuff from you.

  • @ahuddleofpenguins4842
    @ahuddleofpenguins4842 2 года назад

    Never even touched code before. Thanks for the vid!

  • @shreydixit2690
    @shreydixit2690 3 года назад +11

    Another great video! Keep it Up

    • @mCoding
      @mCoding  3 года назад +7

      Thanks! Will do!

  • @user-jb7no2kv8f
    @user-jb7no2kv8f 2 года назад

    The best plus equal explanation I have ever saw on yb

  • @monkeecrap
    @monkeecrap 3 года назад +1

    Another great video! Love learning these detailed but important nuances of Python.

    • @mCoding
      @mCoding  3 года назад

      More to come!

  • @amikomalania3406
    @amikomalania3406 3 года назад +7

    "that can get you into a lot of trouble if you're not familiar how python works" ... and that's why it's not a feature rather a bug(to me).
    That was one of the first serious case that had my and Python's relationship in trouble. "Fluent Python" also demonstrates this type of example and it had my mind blown away. You cannot just report an error on something and then do that exact thing anyways.
    Other than that, great video! I don't think i've seen this "bug" covered elsewhere. It'd be cool if you covered data-model more in depth. Thanks!

    • @mCoding
      @mCoding  3 года назад

      Well, feature or bug, it's not that big a deal once you understand!

  • @nO_d3N1AL
    @nO_d3N1AL 2 года назад +2

    3:40 Interesting that the id is different every time. I presume it is derived from the memory location, similar to the default hashCode implementation in Java?

  • @Speglritz
    @Speglritz 3 года назад

    If you use an integer which is sufficiently maybe the reference will not change. From my own experiements I've seen that python shares reference for small numbers, presumably because they are used very often and will be a benefit to performance.

  • @hannesthiersen8170
    @hannesthiersen8170 2 года назад +5

    I honestly didn't know the += operator can be used on anything other than arithmetic data types in python. However, is it really more convenient and clear compared to the append and extend methods for lists for the sake of argument? Nevertheless it's good of you to point this out. Thanks.

    • @mdcoulson
      @mdcoulson Год назад

      You can use any operator on any object as long as the method called by the operator is defined for the object. This is just the fundamental concept embraced by the object-oriented programming paradigm.
      Create a new class with the __getitem__() dunder method defined and suddenly you can use the indexing operator on any object instantiated by your new class, and it will execute whatever you defined it to execute, regardless of whether it has anything to do with indexing at all.
      Most of these "gotcha"-level videos revealing new information have less to do with actually introducing new information and more to do with just exposing our laziness in applying already understood knowledge. We all know operations in Python are in-place or not, so understanding whether the augmented operators are in-place operators is just a consequence of whether we bothered to read the documentation regarding them.

  • @justinfuruness7954
    @justinfuruness7954 3 года назад +2

    Saw this in a pycon video the other day. Super interesting!

    • @mCoding
      @mCoding  3 года назад +1

      Oh no! someone else covered it first!

  • @Zoltag00
    @Zoltag00 3 года назад +3

    I would be interested in hearing your views about Pythons behaviour when returning from a finally block (how it implicitly discards any unhandled exceptions prior to the finally block)

    • @mCoding
      @mCoding  3 года назад +1

      That would be a good video topic. Generally, you probably don't want to do things that pep8 unconditionally discourages :)

  • @nicko1227
    @nicko1227 3 года назад +1

    This channel is a rare treasure of useful secrets we never knew. Thanks for the great content. Looking forward to more of useful videos.

    • @mCoding
      @mCoding  3 года назад

      Thanks for watching!

  • @supercellodude
    @supercellodude Год назад

    Operator overloading is quite tricky for maintaining clarity and correctness whether it's C++, Python, Haskell ...
    I think the nature of overloading "hiding" function calls is what partly inspired the Zig language from the perspective of C++

  • @lepsycho3691
    @lepsycho3691 3 года назад +2

    When I first started coding in python coming from c++, I was baffled by the fact that there was no '++' to augment an integer and that I had to use the '+='. How naive I was back then! But even though I understand now that the pythonic way of doing things, rarely if ever need an index for a loop, I did not understand the specific reason why It is that way.
    Thank you for this amazing explanation!

    • @mCoding
      @mCoding  3 года назад +2

      Indeed! I pretty much never plus equals for integers.

    • @Starwort
      @Starwort 3 года назад +2

      @@mCoding you should always use += where it makes sense (note that for lists etc. they have an extend method which is usually better) as it allows the implementation to optimise the operator, which is also the reason for the behaviour explained here. += is always the right choice, except when there's an appropriate method

  • @MauriceWilliams
    @MauriceWilliams 3 года назад

    Bro, why did you cook my brain like that? I only understood about 20% of what you were saying.

  • @angello9203
    @angello9203 Год назад

    I've almost never used it, only for increasing numerical variables, but the documentation that I check out when learning always had alternative methods that it's suggested to use

  • @cebtibia
    @cebtibia 3 года назад +4

    Amazing content! Keep the great work!

    • @mCoding
      @mCoding  3 года назад

      Appreciate it!

  • @brawldude2656
    @brawldude2656 2 года назад

    Now I'm going to use "+=" with try except block when i want to assign a tuple member.
    Thank you mCoding now i know how to use this "feature".

  • @fejfo6559
    @fejfo6559 3 года назад +3

    here I was thinking a+=b was just syntax sugar for a = a+b

    • @mCoding
      @mCoding  3 года назад

      Not a bad assumption! This is what it means in some languages for primitive types!

  • @gambiando
    @gambiando 3 года назад

    Wow I was running into a "bug" because of this feature and didn't know this was the cause. Thank you and thank RUclips recommendation for popping this out on my feed.

  • @rizerphe
    @rizerphe 3 года назад +45

    Now I have even more reasons to learn functional programming

    • @casperes0912
      @casperes0912 3 года назад +10

      And I have even more reason to hate Python! :D

    • @mCoding
      @mCoding  3 года назад +18

      All languages have their ups and downs!

    • @johannestafelmaier616
      @johannestafelmaier616 3 года назад +3

      luckily, Python has a few very neat features that allow for pure functional programs, like lambda, yield and defs inside defs... :)
      can't image programming without those nowadays

    • @welltypedwitch
      @welltypedwitch 3 года назад +1

      @@johannestafelmaier616 Wait, what does yield have to do with pure fp?

    • @casperes0912
      @casperes0912 3 года назад +2

      @@mCoding no doubt. Python and I don’t get along well though I have to use it for some parts of my work. I can see why some people really like it and I do acknowledge its strengths. But it’s just really not my preference to work with. I jokingly tell my colleagues I’d rather write pure assembly but it’s all tongue and cheek and I respect Guido and his work with python as well as everyone else involved and of course everyone who’s good at programming in python. It’s just preference and my preference is elsewhere.

  • @GabrielsEpicLifeofGoals
    @GabrielsEpicLifeofGoals 3 года назад +4

    "It's not a bug it's a feature. *wink wink*
    But sir, whould we-
    *points gun* I SAID ITS A FEATURE WIN WINK

  • @Achrononmaster
    @Achrononmaster 3 года назад +3

    "Make sure the thumbs up has changed color once and only once before you leave." Anyone got a problem with that?

    • @mCoding
      @mCoding  3 года назад

      What about colorblind people?

  • @1234567qwerification
    @1234567qwerification Год назад

    Another sharp corner only slightly touched here is that .append() would do flawlessly on a list item in a tuple, because it preserves the constant pointer.

  • @Insomn3s
    @Insomn3s 3 года назад

    Great job! Thank you for your videos!

    • @mCoding
      @mCoding  3 года назад

      Glad you like them!

  • @youuuuuuuuuuutube
    @youuuuuuuuuuutube 2 года назад

    - Something is broken, can you fix the bug?
    Python programmer: it's not a bug, it's a feature!

  • @michaeledwardharris
    @michaeledwardharris Год назад

    Fascinating, once again. You are an excellent teacher. I think the += behavior in python is highly questionable lol.

  • @chaosopher23
    @chaosopher23 2 года назад

    I have always been suspect of shorthand expressions. x = x + 1 is how I learned when BASIC had line numbers, C/C++ came along and made me hang a semicolon at the end of it, and Python circumcised it off for me again. x = x + 1 is more readable.

  • @MidnightSt
    @MidnightSt Год назад

    this confirms my intuitive assumption that every sensible language implements "+=" just as a syntactic sugar for "var = var + value"

  • @egehurturk6209
    @egehurturk6209 3 года назад

    This channel is literally on fire

  • @dewaard3301
    @dewaard3301 Год назад

    This is the kind of unexpected behavior that will have you stuck on a bug for days.

  • @TechSY730
    @TechSY730 Год назад

    With the benefit of bindsight, there probably should have been two different dunder methods.
    * One for when the return should be reassigned to the left side of the +=
    * That returns nothing (except for possibly NotImplemented). The change would be expected to happen to the first parameter (usually 'self')
    That way, when trying to do += on members or elements, Python would know whether to do the final reassignment based on which is present (or which one doesn't return NotImplemented).
    Of course this raises the issue of what to do if both are present, or which order they should be attempted in. So it would be a new sharp corner about _implementing_ +=
    But that moves the sharp corner to the implementer, not the user of the API. But that still would have been a worthwhile improvement.

  • @RoiEXLab
    @RoiEXLab 3 года назад +6

    I already kinda knew this inconsistency because coming from other languages you'd expect
    x += y
    to be short hand for
    x = x + y
    Which as you explained isn't true for lists.
    If it were just a short hand expression it would completely avoid this Problem and python could just add another operator for in-place addition to make up for the missing functionality.
    But yeah, nice video and i learned something new

  • @neiliusflavius
    @neiliusflavius 2 года назад +1

    It feels as if they would have been better off not adding these operators to the language. They mean something clear in other languages but that doesn't fit well with the data model of Python so it would have been clearer to force the one extra keystroke of x=x+1 instead of x+=1.

  • @paxdriver
    @paxdriver 3 года назад

    Great channel! New sub. Thanks much, can't wait to binge your videos all weekend 😊👍

  • @adamsmith7630
    @adamsmith7630 3 года назад

    Reminds me of the mutable default argument "gotcha." def frobnicate(foo=[]): foo.append(1); return foo; has surprising behavior when you run with the default argument more than once.

    • @joseville
      @joseville 3 года назад

      Yeah, that was surprising.
      You just keep attending to the same list.
      best to handle that I know this is
      def foo(l=None):
      l = l or []
      ...

  • @realansgar
    @realansgar 3 года назад +1

    So how should a custom class implement __iadd__ to not change the object itself? In other words, how should BadList be changed to behave like list, where __iadd__ works regardless of scope.

    • @mCoding
      @mCoding  3 года назад +1

      iadd is supposed to modify self (e.g use self.extend(other)) and return self if possible! This is already what the builtin list does, thankfully

  • @error1number404
    @error1number404 3 года назад

    if i not wrong, numbers from 0 to 255 has preset id and it is one of the reason of changing id there 3:30

  • @georgeskhater487
    @georgeskhater487 3 года назад +7

    Let's stick to .append shall we. Btw is there a difference between += or .append for a list?

    • @NateROCKS112
      @NateROCKS112 3 года назад

      Yes, because += acts like extend, not append. Otherwise, not to my knowledge.

    • @georgeskhater487
      @georgeskhater487 3 года назад +1

      @@NateROCKS112 oh okay thanks I didn't even know += was a thing for lists tbh I just assumed

    • @mCoding
      @mCoding  3 года назад

      Append, extend, it's all the same for one element!

    • @simonconrad4402
      @simonconrad4402 3 года назад

      @@georgeskhater487 += is cooler because you can use it in one liners :P

    • @Starwort
      @Starwort 3 года назад

      @@simonconrad4402 ...extend can be used everywhere += can and more?

  • @Cucuska2
    @Cucuska2 3 года назад

    Whoah, this was such a cool video!

  • @bobsquaredme
    @bobsquaredme 2 года назад +1

    I don't see the issue here (except for the mutate-then-error behaviour, that _is_ weird). Tuples are unmodifiable, lists are modifiable, integer primitives are immutable. You can implement iadd in an immutable or mutable manner, just like any other method. If you're publishing the code anywhere, it should be documented

  • @felipedezotti5879
    @felipedezotti5879 3 года назад

    Incredible! Always read that tuples were immutable and they are, but no so much

    • @mCoding
      @mCoding  3 года назад +1

      The rabbit hole goes even deeper than I mentioned in this video…

  • @dtkedtyjrtyj
    @dtkedtyjrtyj 3 года назад +1

    I found all of these example completely obvious, natural and well... correct.
    It's not even weird, how _else_ would they work?
    ...I may have used Python extensively during my formative years.

    • @mCoding
      @mCoding  3 года назад

      I should make a duplicate video of += in C++ and that will scar you!

    • @dtkedtyjrtyj
      @dtkedtyjrtyj 3 года назад

      @@mCoding I developed php for eight years, C++ doesn't scare me.

  • @Aditya-ne4lk
    @Aditya-ne4lk 3 года назад +3

    How do you come across these quirks?

    • @mCoding
      @mCoding  3 года назад

      I push every language to its limits and get burned!

  • @aryanparekh9314
    @aryanparekh9314 3 года назад +17

    Here before this channel blows up!

    • @mCoding
      @mCoding  3 года назад +4

      Thank you so much for your support!

  • @jenselstner5527
    @jenselstner5527 3 года назад +1

    Use C: Make it complicated. Use Python: Add complexity.
    Even I do not use Python to program with, it's enlightened to see it's pitfalls.

    • @mCoding
      @mCoding  3 года назад

      Pitfalls, or necessary consequences? Sometimes it's hard to tell!

    • @jenselstner5527
      @jenselstner5527 3 года назад +1

      @@mCoding I see them as pitfalls, because it breaks intuition.

  • @robertbrummayer4908
    @robertbrummayer4908 2 года назад

    Great job!

  • @liang3163
    @liang3163 3 года назад +1

    To summarize, for mutable variable m1, "+=" will create a new mutable variable m2, and then copy the content of m1 into m2.
    Just remember "+=" will always create a new object and that's it

    • @liang3163
      @liang3163 3 года назад

      Sorry, just ignore this comment, what I sad is wrong.

  • @oleksiihurov
    @oleksiihurov 3 года назад

    Will there be more weirdness for hashable types (additional step in whole assignment procedure) where the += operator defined?

    • @mCoding
      @mCoding  3 года назад

      I don't think the hash will come into play, perhaps someone else has a counterexample?

  • @rosiefay7283
    @rosiefay7283 3 года назад

    3:42 "Must have changed the object that x points to". I thought you said it's immutable. Do you mean that it must have changed x so as to point to a different object? Now if we say x=1; y=x; x=2; then what is the value of y? What is the semantics of y=x? Does y get assigned the address held by x, or does y get assigned the address of an object whose value is the value at the address held by x?

    • @Quantris
      @Quantris 3 года назад

      Yes x now points to a different immutable integer.
      In your example, y = 1.
      I suspect that Python programmers that find this confusing / surprising may have learned Python from tutorials and never actually read the documentation (so do that!)

  • @gregorymorse8423
    @gregorymorse8423 3 года назад +3

    Immutable integer types seems ridiculously inefficient, I've never understood such design decision. Ideally mutable and immutable types are available and the programmer chooses the appropriate one. In cryptography code with lots of math on big integers for example, mutable variants are far better performing unless you need a copy returned and then you want immutable. Why cant we have the best of both at our disposal.

  • @1mikegrn
    @1mikegrn 3 года назад

    Easiest way to mitigate this potential issue is to use the provided builtin methods. x = ([0], [0]); x[0].extend([1,2]) works perfectly fine.

  • @Soljarag5
    @Soljarag5 3 года назад

    Super interesting information!

    • @mCoding
      @mCoding  3 года назад

      Glad it was helpful!

  • @joseville
    @joseville 3 года назад

    With your custom 'iadd' and 'add', does 'a += [1, 2, 3]' become equivalent to 'a + [1, 2, 3]'. I don't get where the assignment back to 'a' is taking place.
    Also what happens when you call 'append_some_to_list' with s normal list?

    • @mCoding
      @mCoding  3 года назад +1

      a += [1,2,3] is closer to a = a + [1,2,3] with the custom iadd and add. Python always does an additional assignment when you use +=, even if it is just reassigning a variable back to itself (which is the most common case). When you do the same example with the builtin list, you get [1,2,3,4,5,6], in contrast to bad list which gives [1,2,3]. Hence the confusion!

  • @MrSteini124
    @MrSteini124 3 года назад

    Love your content!

    • @mCoding
      @mCoding  3 года назад

      I appreciate that!

  • @auto_ego
    @auto_ego 3 года назад

    Please keep making content like this.

  • @user-md7yv4mw7e
    @user-md7yv4mw7e 3 года назад +3

    Vietnam/C++ copy move constructor flashbacks from this video)
    Really nice knowledge about python

    • @mCoding
      @mCoding  3 года назад +1

      Haha, we've all been there!

  • @equenos
    @equenos Год назад

    This thing almost made me loose my sanity when I tried to implement it in one of my projects. Basically I wanted to make a dummy class that would do nothing on __iadd__ except memorising that __iadd__ was called. And due to other implementation details this __iadd__ ended up setting weird attribute values to other seemingly unrelated objects. It took me a while to figure out the reason

  • @lucaspacheco1081
    @lucaspacheco1081 3 года назад

    These videos are great even for experienced coders, great work!

    • @mCoding
      @mCoding  3 года назад

      Glad to hear that!

  • @yiannifunataoldotcom
    @yiannifunataoldotcom 3 года назад

    I really really like your videos!!!

    • @mCoding
      @mCoding  3 года назад

      Thanks for your support!

  • @Lo323984
    @Lo323984 3 года назад +1

    Does this also apply to the non in-place += operator? I.e. x = x + 1. I assume not, since iadd is not called there.

    • @mCoding
      @mCoding  3 года назад +3

      Actually, x=x+1 does something completely different! Furthermore, a raw plus operation is expected to make a copy, not modify the original, and also, a raw equals sign is expected to rebind the variable.

  • @raghuvanshmani8185
    @raghuvanshmani8185 3 года назад

    How great it is to MASTER BASICS at this lvl. !!

    • @mCoding
      @mCoding  3 года назад

      A strong foundation is incredibly important!

  • @michaelcorbett4236
    @michaelcorbett4236 3 года назад +3

    Python is built on C. Arrays always have the first element as the pointer, so as you increase the list size the memory address stays the same. Integers don't tend to do this in C. The value is either written into a new memory location or it uses an enumerated one.

    • @zokalyx
      @zokalyx 2 года назад +1

      CPython is built on C. Python itself is an abstract language, with no pointers or adresses.

  • @quack3891
    @quack3891 3 года назад +1

    Me: *doesn't use python at all since I use C++ on more occasions*
    also Me: "ooh new video from mCoding about python? time to drop my projects and watch"

    • @mCoding
      @mCoding  3 года назад

      I appreciate it so much!

  • @12345origamimaster
    @12345origamimaster 3 года назад +3

    Ive had a bad experience with this in a sorting simulator... best way i had was to return the lists from the functions

    • @mCoding
      @mCoding  3 года назад +3

      Yeah, it kind of forces you to use temporaries

  • @HansBezemer
    @HansBezemer 3 года назад +6

    .. so much for the "intuitiveness" of Python. I'd rather use C. At least I can approximately predict what assembly it punches out instead of tearing my hair out trying to figure out why this thing does something I did not ask for.

  • @tech-learner4555
    @tech-learner4555 10 месяцев назад

    4:36 can we append like this?
    x = [ ]
    x += 1
    ??

  • @piotr780
    @piotr780 3 года назад +2

    is `id()` useful in comparison to `hash()` ?

    • @mCoding
      @mCoding  3 года назад +1

      The id is a unique number guaranteed to be unique for the life of the program. This can be used for a hash if your objects are immutable and no two different objects should be considered equal.

  • @abhinavanand9719
    @abhinavanand9719 3 года назад

    Was it that x[0].__iadd__(y) "concatenated" the lists x[0] and y and "returned" and resultant list
    Or
    Something similar as below:
    a = x[0]
    a += y #although upto here is enough
    x[0] = a #raised error

  • @alexismandelias
    @alexismandelias 3 года назад

    Helps to think about _x += y_ as _x = x + y_ in order to better understand how things work and why they work like that.

    • @mCoding
      @mCoding  3 года назад +1

      This can help in some cases, but this will lead you astray for how the builtin list behaves. list += is x.extend(y), not x = x+y, and these two will have different behavior if x was passed a function parameter.

    • @alexismandelias
      @alexismandelias 3 года назад

      @@mCoding Never thought of that! I guess it makes sense though, the semantics of += more closely resemble self-modification and not assignment.