subclassing list

Robert Kern rkern at ucsd.edu
Sun Jul 31 19:42:56 EDT 2005


spike wrote:
> I've googled like crazy and can't seem to find an answer to why this
> isn't working.
> 
> I want to create a custom list class that acts as a circular list.
> 
> ie: my_list = (0, 1, 2)
> 
> how I want it to behave:
> 
> my_list[0] -> 0
> my_list[1] -> 1
> my_list[2] -> 2
> my_list[3] -> 0
> my_list[4] -> 1
> ...etc
> 
> so, what I've tried to do is:
> 
> def circular_list(list):
>     def __getitem__(self, i):
>         if (i >= len(self)):
>             return self[i % len(self)]
>         else:
>             return self[i]
> 
> items = circular_list(range(8))
> 
> however, when I want to iterate over it with a for statement, I get:
> 
> TypeError: iteration over non-sequence

You also need to post the code that raises the error, or no one else can 
debug it.

> what am I missing?

I have no idea why you get that error. I do not in Python 2.4.1. 
However, I also don't get what you desire either. Iteration over lists 
(and subclasses of list) hasn't used __getitem__ since Python 2.2.

http://www.python.org/doc/2.2/lib/typeiter.html

In [7]: class circular_list(list):
    ...:     def __getitem__(self, i):
    ...:         return list.__getitem__(self, i%len(self))
    ...:

In [8]: items = circular_list(range(8))

In [9]: for i in items:
    ...:     print i
    ...:
0
1
2
3
4
5
6
7

In fact, if all you need is iteration, use itertools.cycle().

In [6]: itertools.cycle?
Type:           type
Base Class:     <type 'type'>
String Form:    <type 'itertools.cycle'>
Namespace:      Interactive
File: 
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/lib-dynload/itertools.so
Docstring:
     cycle(iterable) --> cycle object

     Return elements from the iterable until it is exhausted.
     Then repeat the sequence indefinitely.

In [11]: class better_circular_list(circular_list):
    ....:     def __iter__(self):
    ....:         return itertools.cycle(list.__iter__(self))
    ....:

In [13]: bcl = better_circular_list(range(8))

In [14]: for i in bcl:
    ....:     print i
    ....:
0
1
2
3
4
5
6
7
0
1
2
<etc.>

-- 
Robert Kern
rkern at ucsd.edu

"In the fields of hell where the grass grows high
  Are the graves of dreams allowed to die."
   -- Richard Harter




More information about the Python-list mailing list