>>> for item in data.items(): item[0], item[1] 874 µs ± 21.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) >>> for key, value in data.items(): key, value 524 µs ± 4.26 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) >>> for item in items_tuple(data): item.key, item.value 5.82 ms ± 117 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Thanks for sharing the results, in particular the amount of difference between "for item in data.items(): item[0], item[1]" and "for key in data.items(): key, value" is a bit surprising to me. I'd have assumed they'd be a bit closer in performance. I expected the named tuple to be significantly slower than the other two, but not quite by that much. Good to know. I'm -1 on the proposal overall. It's not a bad idea, but in practice it would likely be too much of a detriment to performance and backwards compatibility to "dict.items()". I wouldn't be opposed to considering a different method though, such as "dict.named_items()" or something similar that allowed usage of "item.key" and "item.value". On Sun, Dec 1, 2019 at 7:56 AM Wes Turner <wes.tur...@gmail.com> wrote: > My mistake, I skimmed and assumed that the question was asking for this: > > from collections import namedtuple > data = {'1': 1, 'two-2': 2} > x = namedtuple('x', data.keys()) > # ValueError: Type names and field names must be valid identifiers: '1' > > # But now understand that the request was for this: > > from collections import namedtuple > Item = namedtuple('Item', ['key', 'value']) > > def items_tuple(self): > for key, value in self.items(): > yield Item(key, value) > > # So that this test would pass: > > def test_items(): > data = {'1': 1, 'two-2': 2} > for item in data.items(): > assert hasattr('key', item) > assert hasattr('value', item) > key, value = item > assert item.key == key > assert item.value == value > > # FWIW, here are rough timings: > > data = dict.fromkeys(range(10000)) > > def timeit(code): > print(f">>> {code}") > get_ipython().run_line_magic('timeit', code) > > timeit('for item in data.items(): item[0], item[1]') > timeit('for key, value in data.items(): key, value') > timeit('for item in items_tuple(data): item.key, item.value') > > >>> for item in data.items(): item[0], item[1] > 874 µs ± 21.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) > >>> for key, value in data.items(): key, value > 524 µs ± 4.26 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) > >>> for item in items_tuple(data): item.key, item.value > 5.82 ms ± 117 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) > > On Sun, Dec 1, 2019 at 1:24 AM Andrew Barnert <abarn...@yahoo.com> wrote: > > > > On Nov 30, 2019, at 20:21, Wes Turner <wes.tur...@gmail.com> wrote: > > > > > > What about keys that contain invalid characters for attribute names? > > > > What about them? > > > > > items = {'1': 1, 'two-3': 4,} > > > x = object() > > > x.__dict__.update(items) # dangerous > > > x = AttrDict(**items) > > > x.1 # error > > > x.two-3 # error > > > > The message you quoted was about how in Python 2 (but not 3) you could > destructure parameters: > > > > sorted({1:300, 2:4}.items(), key=lambda (key, value): value) > > > > The wider discussion is about how if items() were a view of namedtuples > instead of just sequences you could do something even better: > > > > sorted({1:300, 2:4}.items(), key=lambda it: it.value) > > > > What does either of those have to do with using a dict whose keys are > not identifiers as an attribute dictionary for an object? Neither restoring > Python 2’s parameter destructuring nor making items namedtuples would in > any way affect any of the code you wrote. > > > > > _______________________________________________ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/OA7NQRF4VTFG2DJVNJAAJ7YIQNB3IVVR/ > Code of Conduct: http://python.org/psf/codeofconduct/ >
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/76Y6PK74TLQFWNLE4CO3WAGBUPMQ62WL/ Code of Conduct: http://python.org/psf/codeofconduct/