Is there an official or common knowledge standard minimal interface for a "list-like" object?

Question:

I keep seeing functions and documentation like this and this (to name a few) which operate on or refer to list-like objects.

I’m quite aware of what exactly an actual list is (dir(list)), and can deduce what (often varying) methods from a list are necessary in most references to a “list-like object”, however the number of times I see it referenced has left me with the following question:

Is there an official or common knowledge standard minimal interface for a “list-like” object? Is it as simple as actualizing__getitem__, or is it agreed that additional things like __len__ and __setitem__are required as well?

This may seem like semantics, but I can’t help but think that if there does not exist a standard minimal interface requirement, various ideas of “list-likeness” could cause some issues/improper handling. Perhaps this is just a slight downside to Python’s duck typing?

Asked By: HavelTheGreat

||

Answers:

The technical term for a “list-like object” is sequence. At the very least it supports ordering (i.e. two objects with the same elements but different order are not equal), indexing (foo[bar] such that bar is an integer less than the length of the sequence), and containment checking (in), and has a given length. It should support iteration, but if not then Python will simulate it using indexing.

Pretty much any time you see “-like object” in Python documentation the author is being deliberately vague. The author has decided that enumerating all the required interfaces would be too much trouble, and is only saying that some of its interfaces are required. An object that implemented all the interfaces is guaranteed to work, but in most cases it will work with an object that implements much less.

With a “list-like object” probably the best you can do, short of inspecting the source code, is to infer whether it needs any of the mutable interfaces. If it only needs read-only access to the list, you can be pretty sure you don’t need to implement any of the mutable sequence operations.

If it says “list-like object or iterator” you can provide something that implements the much simpler iterator interface.

Answered By: Ross Ridge

See the collections.abc module. Of the abstract base classes listed there, list in Python implements Iterable, Container, Sized, Sequence and MutableSequence. Now, of these, Iterable, Sequence and MutableSequence could be casually called list-like.

However, I would understand the term list-like to mean that it is a MutableSequence – has at least the methods __getitem__, __setitem__, __delitem__ and __len__, expecting also it to have the mixin methods mentioned in the documentation, such as append.

If there is no need for __setitem__ and __delitem__ it should be called a sequence instead – the assumption is that if something accepts a sequence, it does not need to be mutable, thus str, bytes, tuple etc also work there.


Your two links highlight the vagueness of the term:

The plotly API requires that the list-like objects will be serialized to a JSON array by the internal PlotlyJSONEncoder that delegates most of the encoding to the Python JSONEncoder. However, the latter encodes only tuple and list (and subclasses) to a JSON array; thus the list-like here means a list, a tuple or subclasses thereof. A custom sequence object that is not a subclass of either will result in TypeError: [...] is not JSON serializable.

The unzip recipe you linked to requires an object that behaves like a Sequence, (mutability is not required), thus a tuple or str, or any custom object implementing Sequence will do there.


TL;DR list-like is a vague term. It is preferable to use the terms iterable, sequence and mutable sequence instead, now that these are defined in collections.abc.

Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.