Live data from Hacker News

Migrating to Python 3 with pleasure

github.com

31–40 of 181 posts

Re: Migrating to Python 3 with pleasure

#31

Earlier quoted context omitted.

Dicts are UNORDERED associative containers. If youre depending your app on implementation defined behavior, that's on your developpers shoulders. Stuff like that shouldn't pass code review

Not for much longer, as of 3.7 the ordering is a language feature: https://mail.python.org/pipermail/python-dev/2017-December/1... It's mad that it ever wasn't this way. Mapping-with-ordered-keys is such a useful and pervasive data structure (all database query result rows, for one) that an ordered dictionary should be a fundamental part of a language. It has been so much more pleasant to write python since ordering…

The data structure OrderedDict does what you describe and has been in the stdlib since I think 2.7

Re: Migrating to Python 3 with pleasure

#32
I've been toying around with Python 3 and using it for most of my personal/hack projects, but I somehow missed the unpacking improvements: https://www.python.org/dev/peps/pep-0448/

In particular, being able to create an updated copy of a dict with a single expression is pretty cool:

    return {**old, 'foo': 'bar'}
    
    # Old way
    new = old.copy
    new['foo'] = ['bar']
    return new

Re: Migrating to Python 3 with pleasure

#33
post #32

I've been toying around with Python 3 and using it for most of my personal/hack projects, but I somehow missed the unpacking improvements: https://www.python.org/dev/peps/pep-0448/ In particular, being able to create an updated copy of a dict with a single expression is pretty cool: return {**old, 'foo': 'bar'} # Old way new = old.copy new['foo'] = ['bar'] return new

My mind is blown. Ever since JavaScript added this, I've been wanting it in Python... and somehow it was there all along. It works for lists too!

    [*a, *b, *c]

Re: Migrating to Python 3 with pleasure

#34
post #32

I've been toying around with Python 3 and using it for most of my personal/hack projects, but I somehow missed the unpacking improvements: https://www.python.org/dev/peps/pep-0448/ In particular, being able to create an updated copy of a dict with a single expression is pretty cool: return {**old, 'foo': 'bar'} # Old way new = old.copy new['foo'] = ['bar'] return new

And the performance is pretty much the same, just a lot nicer syntax

    In [1]: x = {1:2, 3:4}

    In [2]: %timeit x[3] = 5
    48.6 ns ± 1.18 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

    In [3]: %timeit y = x.copy(); y[3] = 5
    189 ns ± 3.23 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

    In [4]: %timeit {**x, 3: 5}
    182 ns ± 3.3 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
Edit: It also seems to be pretty constant time if you're just merging:

    In [16]: %timeit {**x, **y, **z}
    180 ns ± 1.29 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

    In [17]: %timeit {**x, **y, **z, 3: 5}
    278 ns ± 18.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

    In [19]: dis.dis(lambda: {**x, **y, **z, 3: 5})
              0 LOAD_GLOBAL              0 (x)
              2 LOAD_GLOBAL              1 (y)
              4 LOAD_GLOBAL              2 (z)
              6 LOAD_CONST               1 (3)
              8 LOAD_CONST               2 (5)
             10 BUILD_MAP                1
             12 BUILD_MAP_UNPACK         4
             14 RETURN_VALUE

     In [20]: dis.dis(lambda: {**x, **y, **z})
              0 LOAD_GLOBAL              0 (x)
              2 LOAD_GLOBAL              1 (y)
              4 LOAD_GLOBAL              2 (z)
              6 BUILD_MAP_UNPACK         3
              8 RETURN_VALUE

Re: Migrating to Python 3 with pleasure

#35

I realized, just today, that the secrets module is new to 3.6 after trying to pip install it. This being provided directly by the language is a game changer, IMHO.

It's interesting for sure, and I'd like to see where it goes, but right now there isn't much to it: https://github.com/python/cpython/blob/3.6/Lib/secrets.py

Re: Migrating to Python 3 with pleasure

#36

Earlier quoted context omitted.

Not for much longer, as of 3.7 the ordering is a language feature: https://mail.python.org/pipermail/python-dev/2017-December/1... It's mad that it ever wasn't this way. Mapping-with-ordered-keys is such a useful and pervasive data structure (all database query result rows, for one) that an ordered dictionary should be a fundamental part of a language. It has been so much more pleasant to write python since ordering…

>>(all database query result rows, for one) What? No. SQL does not return results in any consistent ordering unless specifically instructed to.

Not the result set, the rows of the result set.

Re: Migrating to Python 3 with pleasure

#37

Earlier quoted context omitted.

> test_path = datasets_root / dataset / 'test' > Previously it was always tempting to use string concatenation (concise, but obviously bad), now with pathlib the code is safe, concise, and readable. This is the kind of feature that I'm wary to use even in scripts: questionable benefit, and probably too clever.

I don't have a machine available right now, but I wonder what happens if two adjacent path elements are integers? Does it perform division instead of path/string concatenation?

The Path object won't construct a path from an integer.

    >>> from pathlib import Path
    >>> p=Path(1)
    Traceback (most recent call last):
      File "", line 1, in 
      File "/usr/lib/python3.6/pathlib.py", line 979, in __new__
        self = cls._from_parts(args, init=False)
      File "/usr/lib/python3.6/pathlib.py", line 654, in _from_parts
        drv, root, parts = self._parse_args(args)
      File "/usr/lib/python3.6/pathlib.py", line 638, in _parse_args
        a = os.fspath(a)
    TypeError: expected str, bytes or os.PathLike object, not int
    >>>
So what happens if the paths are numbers? They are treated like any other characters.

Re: Migrating to Python 3 with pleasure

#38

I've moved to python 3 over the past couple of months, after resisting for the better part of a decade. I like it. One surprising thing I learned from this document is that dicts now iterate in assignment order, not hash order. That's going to break some code for people.

EDIT: I was just informed it is as of 3.7 an official language feature, making everything below invalid

Personally, I'm worried people will come to rely on the new behaviour in code instead. As core developers have repeatedly said, dict order is still an implementation detail, it should not be relied on as it is not officially part of the language. Other implementations (except pypy) will probably not have this behaviour.

Yet, I feel like this will fall on deaf ears and become a de-facto part of the language. Blogs will state it as a new feature, Python books will teach it and new coders will rely on it, forever locking the dict internals in place for all python interpreters.

(If you need to rely on ordering, use an OrderedDict instead.)

Re: Migrating to Python 3 with pleasure

#39
post #32

I've been toying around with Python 3 and using it for most of my personal/hack projects, but I somehow missed the unpacking improvements: https://www.python.org/dev/peps/pep-0448/ In particular, being able to create an updated copy of a dict with a single expression is pretty cool: return {**old, 'foo': 'bar'} # Old way new = old.copy new['foo'] = ['bar'] return new

    return {**old, 'foo': 'bar'}
    
    # Old way
    return dict(old, foo='bar')
Not much difference if you ask me.

Re: Migrating to Python 3 with pleasure

#40
post #39
post #32

I've been toying around with Python 3 and using it for most of my personal/hack projects, but I somehow missed the unpacking improvements: https://www.python.org/dev/peps/pep-0448/ In particular, being able to create an updated copy of a dict with a single expression is pretty cool: return {**old, 'foo': 'bar'} # Old way new = old.copy new['foo'] = ['bar'] return new

return {**old, 'foo': 'bar'} # Old way return dict(old, foo='bar') Not much difference if you ask me.

I've been practicing Python for a while and didn't even know about this. In my code style, I try to completely avoid the "dict" keyword and exclusively use dict literal notation.
Post reply on HN