Suggestion: make sequence and map interfaces more similar

Terry Reedy tjreedy at udel.edu
Tue Mar 29 20:55:08 EDT 2016


On 3/29/2016 6:29 PM, Marco Sulla via Python-list wrote:

> Let me add that an items() and keys() for sequences will be also
> useful for day-by-day programming, since they will be a shortcut for
> enumerate(seq) and range(len(seq))

To me they are useless and confusing duplications since enumerate()(seq) 
and range(len(seq)) are quite different from dict.items and dict.keys. 
They cannot be used interchangably.

Dict.keys/values/items are re-iterable, set-like *dynamic views* of 
dicts.  They are not iterators.  They support binary set operations and 
inter-operate with sets.

 >>> {1:1, 2:2}.keys() ^ {1, 3}
{2, 3}
 >>> {1, 3} ^ {1:1, 2:2}.keys()
{2, 3}

They not independent objects but are views of the contests of the dict. 
They are relatively easy to implement because dicts are key-hashed sets 
of pairs. At least in CPython, changing a dict disables view iterators.

 >>> d={1:1, 2:2}
 >>> di = iter(d)
 >>> next(di)
1
 >>> d[3] = 3
 >>> next(di)
Traceback (most recent call last):
   File "<pyshell#8>", line 1, in <module>
     next(di)
RuntimeError: dictionary changed size during iteration

Enumerates are iterators.  Ranges are independent collections.  Neither 
support binary set operations.  Enumerates and range iterators are not 
disabled by sequence changes.

> Since simply adding get(), items(), keys(), values() to existing
> sequence interface will likely break existing code, I would try also
> to write new sequence types, using a common interface with maps.

seq.get is plausible, but the use cases are not clear.  It is trivial to 
write, so it needs justification.  A major use of dict.get is to supply 
an empty list for values that can be appended to.
    d.get(key, []).append(val)
A similar use with lists could just as well be done with a dict.

For the rest, try writing sequence view classes that actually mimic dict 
views and interoperate with sets and views.  Find the dict view tests 
and adapt them to seq views.  To use the same code with dicts and seqs, 
add functions that return a dict view or seq view depending on the class 
of the collections.

     def keys(ds):
         reture ds.keys() if isinstance(ds, dict) else SeqKeys(ds)

You might search for 'python sequence view' first, and if there is 
nothing already on PyPI, add a seqview module there.

-- 
Terry Jan Reedy




More information about the Python-list mailing list