[Python-ideas] Why operators are useful

Raymond Hettinger raymond.hettinger at gmail.com
Fri Mar 15 22:27:34 EDT 2019



> On Mar 15, 2019, at 6:49 PM, Chris Angelico <rosuav at gmail.com> wrote:
> 
> On Sat, Mar 16, 2019 at 12:40 PM Raymond Hettinger
> <raymond.hettinger at gmail.com> wrote:
>> Also, it seems like the efficiency concerns were dismissed with hand-waving. But usually, coping and updating aren't the desired behavior. When teaching Python, I like to talk about how the design of the language nudges you towards fast, clear, correct code.  The principle is that things that are good for you are put within easy reach. Things that require more thought are placed a little further away.  That is the usual justification for copy() and deepcopy() having to be imported rather than being builtins.  Copying is an obvious thing to do; it is also not usually good for you; so, we have you do one extra step to get to it.
>> 
> 
> I'm not sure I understand this argument. Are you saying that d1+d2 is
> bad code because it will copy the dictionary, and therefore it
> shouldn't be done? Because the exact same considerations apply to the
> addition of two lists, which already exists in the language. Is it bad
> to add lists together instead of using extend()?

Yes, that exactly.

Consider a table in a database. Usually what people want/need/ought-to-do is an SQL UPDATE rather than copy and update which would double the memory requirement and be potentially many times slower.  The same applies to Python lists. Unless you actually have a requirement for three distinct lists (c = a + b), it is almost always better to extend in place.  Adding lists rather than extending them is a recipe for poor performance (especially if it occurs in a loop):


Raymond



---- Performant version ----

s = socket.socket()
try:
    s.connect((host, port))
    s.send(request)
    blocks = []
    while True:
        block = s.recv(4096)
        if not block:
            break
        blocks += [block]                   # Normally done with append()
    page = b''.join(blocks)                          
    print(page.replace(b'\r\n', b'\n').decode())
finally:
    s.close()

---- Catastrophic version ----

s = socket.socket()
try:
    s.connect((host, port))
    s.send(request)
    blocks = []
    while True:
        block = s.recv(4096)
        if not block:
            break
        blocks = blocks + [block]              # Not good for you.
    page = b''.join(blocks)                          
    print(page.replace(b'\r\n', b'\n').decode())
finally:
    s.close()



More information about the Python-ideas mailing list