Circular List Iterator in Python

Circular list iterator in Python

Use itertools.cycle, that's its exact purpose:

from itertools import cycle

lst = ['a', 'b', 'c']

pool = cycle(lst)

for item in pool:
print item,

Output:

a b c a b c ...

(Loops forever, obviously)


In order to manually advance the iterator and pull values from it one by one, simply call next(pool):

>>> next(pool)
'a'
>>> next(pool)
'b'

Circular Iterator in Python

As you mentioned you can use a deque which happens to be in the standard library:

from collections import deque

startPosition = 1
data = [1,10,20]

d = deque(data)
d.rotate(-startPosition)

You have to negate the direction of rotate because by default it does a rotation to the right.

How to create a circular list of a given length from a list

newtaglist can be generated using a modulo operator to make sure the index is in range

taglist = ["faint", "shocking", "frosty", "loved", "sadness"]
num_list = [1,2,3,4,5,6,7]
newtaglist = [taglist[i % len(taglist)] for i in xrange(len(num_list))]

Yielding:

['faint', 'shocking', 'frosty', 'loved', 'sadness', 'faint', 'shocking']

Run it here

Circular linked list code is getting into infinite loop

I'll break the steps down.

First, I rename Link to Node.

class Node(object):
def __init__(self, data, next=None):
self.data = data
self.next = next

Links aren't the same as nodes - nodes are what hold your data, and links connect two nodes together.

Next, the CircularList class, needs some changes.

__init__ will need to initialise an empty list. That means no nodes at all. For the sake of convenience, I define self.last to greatly simplify the code (note, greatly, you will have a harder time of things otherwise).

class CircularList(object):
def __init__(self):
self.first = self.last = None

For insert_first, you will need to take care of a corner case when the list is empty, and the general case. Update self.first and self.last accordingly.

def insert_first(self, item):
if self.first is None:
self.first = self.last = Node(item)
self.first.next = self.first
else:
self.first = Node(item, self.first)
self.last.next = self.first

Your __iter__ method should also respond in kind. Comments inlined.

def __iter__(self):
# corner case - yield empty list
if not self.first:
yield []
else:
# start by yielding the head node
yield self.first
cur = self.first.next
# iterate as long as you do not see the head node again
while cur is not self.first:
yield cur
cur = cur.next

The other methods remain the same. Test code:

a = CircularList()
for i in [5, 4, 3, 2, 1]:
a.insert_first(i)

print(a)
[1, 2, 3, 4, 5]

Full Code Listing

class Node(object):
def __init__(self, data, next=None):
self.data = data
self.next = next

class CircularList(object):
def __init__(self):
self.first = self.last = None

def insert_first(self, item):
if self.first is None:
self.first = self.last = Node(item)
self.first.next = self.first
else:
self.first = Node(item, self.first)
self.last.next = self.first

def __iter__(self):
if not self.first:
yield []
else:
yield self.first
cur = self.first.next
while cur is not self.first:
yield cur
cur = cur.next

def __str__(self):
return str([Link.data for Link in self])

def __repr__(self):
return self.__str__()

Cyclically calls of list elements in a loop, which restart from the first one when the list is ended

I will try to solve this in different approach. I simply applied even/odd method...If J is even print blue else print red

colors = ['red', 'blue']
for x in range(6):
if x%2==0:

firstElement = colors[0]
print(firstElement)

else:
print(colors[1])

Iterate over pairs in a list (circular fashion) in Python

I've coded myself the tuple general versions, I like the first one for it's ellegant simplicity, the more I look at it, the more Pythonic it feels to me... after all, what is more Pythonic than a one liner with zip, asterisk argument expansion, list comprehensions, list slicing, list concatenation and "range"?

def ntuples(lst, n):
return zip(*[lst[i:]+lst[:i] for i in range(n)])

The itertools version should be efficient enough even for large lists...

from itertools import *
def ntuples(lst, n):
return izip(*[chain(islice(lst,i,None), islice(lst,None,i)) for i in range(n)])

And a version for non-indexable sequences:

from itertools import *
def ntuples(seq, n):
iseq = iter(seq)
curr = head = tuple(islice(iseq, n))
for x in chain(iseq, head):
yield curr
curr = curr[1:] + (x,)

Anyway, thanks everybody for your suggestions! :-)

Create circular iterator from incremental start position

Here is my code:

a = [1, 2, 3, 4, 5]
for slice_index in range(0, len(a)):
print (a[slice_index::] + a[:slice_index:])

[1, 2, 3, 4, 5]

[2, 3, 4, 5, 1]

[3, 4, 5, 1, 2]

[4, 5, 1, 2, 3]

[5, 1, 2, 3, 4]

Explanation: a[slice_index::] gives the part of array where index >= slice_index. Same for the other.

How to slice a circular list iteratively ? (Python 2.7)

To make a "true" circular pair of numbers, you should incorporate some itertools:

from itertools import cycle, islice, izip

circ_list = izip(cycle(nums), islice(cycle(nums), 1, None))

This is an endless iterator which will keep yielding the kinds of number pairs you want.

cycle(nums) will endlessly repeat your list of numbers, islice(..., 1, None) skips the first item of it, so you essentially have [0, 1, 2, ...] and [1, 2, 3, ...], which izip combines.

You can now for example take a small slice of it:

>>> list(islice(circ_list, 5))
[(0, 1), (1, 2), (2, 3), (3, 0), (0, 1)]

How to iterate a list starting from different index, and also wrap around

One approach would be using collections.deque:

from collections import deque
from itertools import repeat

d = deque(['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'])

n = 7
for i in repeat(d, n):
print(*i, sep='\n')
print('-----')
i.rotate(-1)

Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
-----
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
-----
Tuesday
.
.
.

Though you might find more interesting to create a nested list:

n = 7
l = []
for i in repeat(d, n):
sl = []
for j in i:
sl.append(j)
l.append(sl)
i.rotate(-1)

print(l)
# [['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
# ['Monday', 'Tuesday', 'Wednesday'...


Related Topics



Leave a reply



Submit