re-awakening this thread, because I just happened on an actual real-world use case:

I need the first 255 items in a dict, as a dict. Order is important, and I can count on an order-preserving dict.

I ended up with:

from itertools import islice

smaller_dict = dict(islice(large_dict.items(), 0, 255))

which works, and isn't doing an unnecessary copying but it's pretty darn ugly, as far as I'm concerned.

I could also do it the old fashioned way:

smaller_dict = {}
for k, v in dict.items():
    if i > 255:
        break
     smaller_dict[k] = v

which is worse.

I'd much rather:

dict(large_dict.items[:255])

I'd even more prefer:

dict[:255]

which would, in theory be possible, as slices are not hashable, so no one is doing this in current code as an actual dict key, but yeah, that's too much magic to ask for.

To be fair, this isn't that much data, and it's in memory already, so:

dict(tuple(large_dict.items())[:255])

would work just fine. but as Python has moved toward a lot more iterables, and lazy evaluation, it seems like we shouldn't have to make a full copy, just to pull a fraction of something out.

Note that this is related to an earlier thread I started about having a way to lazy-slice a Sequence -- essentially islice, but with slice syntax.

This is also related a bit to another thread about keywords in indexing -- there were examples there where it would be nice to have slice syntax in more places, like function calls. then this could be:

So: anyone have a cleaner way to accomplish this without any changes to Python?

This is still an oddball use case, so may not be a reason to change Python -- but it IS a real world, operational code, use case :-)

-CHB



On Sun, Jul 12, 2020 at 9:55 PM Christopher Barker <pythonchb@gmail.com> wrote:
On Sat, Jul 11, 2020 at 1:33 PM David Mertz <mertz@gnosis.cx> wrote:
On Sat, Jul 11, 2020 at 3:45 PM Christopher Barker <pythonchb@gmail.com> wrote:
random.choice(the_dict.keys())

is a little easier than:

random.choice(list(the_dict.keys())

Ummm... don't you mean:

random.choice(list(the_dict))

well, sure, though I have to say that I think that that's an unfortunate confusing thing about python dicts. IN fact, I doubt there are many uses at all for dict.keys() -- most uses can jsut use the dict.

I certainly see newbies write:

if this in dict.keys():

pretty often.

maybe adding indexing to the dict views will give the dict_keys object more reason to exist :-)

-CHB






 
If it's keys you care about I've saved you one character over your proposed style, while also reading better to me.  It's only for .items() where it doesn't work.  And honestly, just looking up the value from the random key is not hard.

In any case, if "reservoir sampling" is the goal here, we should just add a function `random.reservoir_sample()` to accommodate using iterators rather than sequences (https://en.wikipedia.org/wiki/Reservoir_sampling)


--
The dead increasingly dominate and strangle both the living and the
not-yet born.  Vampiric capital and undead corporate persons abuse
the lives and control the thoughts of homo faber. Ideas, once born,
become abortifacients against new conceptions.


--
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython


--
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython