[Python-ideas] Adding a functional list type to the standard library.

Bruce Frederiksen dangyogi at gmail.com
Sun Apr 5 18:35:15 CEST 2009


Alexandre Vassalotti wrote:
> I would like to have your opinion whether a functional list type would
> be welcomed in the standard library. 
I'm wondering how FunctionalLists compare to extending tuples to provide 
all of the list capabilities but by returning new (immutable) objects, 
rather than modifying (or seeming to modify?) the object in place?

For example, if two new implementations of tuple were added: 
slice_tuple(parent_tuple, slice) and subst_tuple(parent_tuple, slice, 
inserted_tuple) to obviate copying the needed parts of the parent_tuple, 
then:

tuple[slice] => return slice_tuple(tuple, slice)
tuple.delete(slice) => return subst_tuple(tuple, slice, ())
tuple.with_append(x) => return subst_tuple(tuple, slice(len(tuple), 
len(tuple)), (x,))
tuple.extended_by(tuple_b) => tuple + tuple_b => return 
subst_tuple(tuple, slice(len(tuple), len(tuple)), x)
tuple.with_subst(slice, tuple_b) => return subst_tuple(tuple, slice, 
tuple_b)
tuple.reversed() => return slice_tuple(tuple, slice(None, None, -1))

If it's not clear, I'm imagining that slice_tuple (for example) be 
implemented something like:

class slice_tuple(base_tuple):
    def __init__(self, parent_tuple, slice):
        self.parent = parent_tuple
        self.step = slice.step or 1
        # Convert negative and out of bound slice.starts to make 0 <= 
self.start < len(self.parent).
        if slice.start is not None:
            self.start = slice.start if slice.start >= 0 else 
slice.start + len(self.parent)
            if self.start < 0: self.start = 0
            elif self.start > len(self.parent): self.start = 
len(self.parent)
        else:
            self.start = 0 if self.step > 0 else len(self.parent) - 1
        # Convert negative and out of bound slice.stops to make -1 <= 
self.stop <= len(self.parent)
        # and (self.stop >= self.start if self.step > 0 else self.stop 
<= self.start).
        if slice.stop is not None:
            self.stop = slice.stop if slice.stop >= 0 else slice.stop + 
len(self.parent)
            if self.step > 0:
                if self.stop < self.start: self.stop = self.start
                elif self.stop > len(self.parent): self.stop = 
len(self.parent)
            else:
                if self.stop > self.start: self.stop = self.start
                elif self.stop < -1: self.stop = -1
        else:
            self.stop = len(self.parent) if self.step > 0 else -1
    def __len__(self):
        if self.step > 0:
            return (self.stop - self.start + self.step - 1) // self.step
        return (self.stop - self.start + self.step + 1) // self.step
    def __getitem__(self, i):
        if i < 0: i += len(self)
        if i < 0 or i >= len(self): raise IndexError("tuple index out of 
range")
        return self.parent[self.start + i * self.step]
    ... etc ...

-bruce frederiksen



More information about the Python-ideas mailing list