Search code examples
pythonlistpython-3.xqueueradix

Radix sorting, "Queue" object not iterable


I've come to an end with my assignment, I don't know where I go from where I am right now, the code is currently looking like this:

def radixsorting1(n,m):
    div=1
    mod=10
    bin_list=[]
    alist=[]
    r=[]
    s=[]
    for bins in range(0,10):
        bin_list.append(Queue())
    for k in range(0,m):
        r.append(random.randint(1,10**n))
    if not len(r)==0:
        o=max(r)
        y=len(str(o))
    for p in range(y):
        for num in r:
            minsta_tal=num%mod
            minsta_tal=int(minsta_tal//div)
            bin_list[minsta_tal].put(num)
        new_list=[]
        for bins in bin_list:
            while not bins.isempty():
                new_list.append(bins.dequeue())
            alist=new_list
        return alist

What I've been trying to do is to create 10 queues in put them in a list, then random m numbers from 1 to 10^n. Lets say I get 66 and 72, then I first sort them by the "small number", that is 6 and 2 in my numbers, then put them in a lost, and then do the process all over again but for the number 6 and 7 (the bigger number). In its current shape I get the error "Queue" object is not iterable.

My Queue class is looking like this, I think this one is okay.

class Queue:
    def __init__(self):
        self.lista=[]

    def put(self,x):
        self.lista.append(x)

    def get(self):
        if not len(self.lista)==0:
            return self.lista.pop(0)

    def isempty(self):
        if len(self.lista)==0:
            return True
        else:
            False

    def length(self):
        return len(self.lista)


    def dequeue(self):
        if not len(self.lista)==0:
            n=self.lista.pop(0)
            return n

Solution

  • You need to add a bit more code to make it an iterable. __iter__ should return an iterator. The iterator should have a next method.

    Take a look at this:

    Build a Basic Python Iterator

    So it is my understanding that the thing you want to iterate over is the contents of self.lista... Why not just return lista's iterator.

    Here is the easiest way to do that:

    class Queue:
        ...
        def __iter__(self):
            return self.lista.__iter__()
    

    It's a bit hard to see what exactly it is that you want.. If what you are trying to do is empty listaas you iterate over it (Queue is a fifo kinda deal) it then rather do this:

    class Queue:
        ...
        def __iter__(self):
            return self
        def next(self):
            if self.lista: #since empty lists are Falsey
                return self.lista.pop(0)
            raise StopIteration