-1

I'm trying to iterate of a list of tuples while still having access to the previous tuple and the next tuple.Specifically I need to compare the y coordinate of the previous current and next tuple.

This is my list of tuples that I'm using as input: [(1,1),(2,2),(3,4),(4,3),(5,5),(6,3.5),(7,7),(8,8),(9,9),(10,8),(11,9.5),(11,7.5),(12,12),(13,1.5)]

I initially used this code segment to be able to have access to the previous, current and next elements:

def previous_and_next(some_iterable):

    prevs, current, nexts = tee(some_iterable, 3)
    prevs = chain([None], prevs)
    nexts = chain(islice(nexts, 1, None), [None])

    return zip(prevs, current, nexts)

But I can't access the elements of the tuple using this function as it returns an error about subscripting. Im open to new ideas or different functions, as this bit is clearly not what I need.

For more clarification this is the function that I am currently trying to implement

UF = UnionFind()
sortedlist = sorted(pointcloud, key=lambda x: x[1])

for previous, current, nxt in previous_and_next(sortedlist):

       if previous[1] > current[1] and nxt[1] > current[1]:
           UF.insert_objects(current)
       elif previous[1] < current[1] and nxt[1] < current[1]:
           c=UF.find(previous[1])
           d=UF.find(nxt[1])
           UF.union(c,d)
       else:
            c=UF.find(previous[1])
            UF.union(current,previous)



return 
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
moose0306
  • 13
  • 6
  • 1
    if you're trying to access the elements of the tuples, of course you'll have an issue when you stumble on `None`. Your last code edit seems to confirm that. either filter the tuples or handle the `None` case. – Jean-François Fabre Mar 28 '18 at 19:57
  • 1
    @wim that's not OP issue. OP issue is that he's accessing `None[1]` without checking that it's not `None` because of start & end points. Nothing to do with slicing or previous or next elements. – Jean-François Fabre Mar 28 '18 at 19:59
  • @Jean-FrançoisFabre I thought a rolling window impl which doesn't yield the endpoints (because they have an invalid prev or next) would help. Maybe not. – wim Mar 28 '18 at 20:03
  • 1
    this isn't a duplicate, but it doesn't make the question any better... – Jean-François Fabre Mar 28 '18 at 20:07

2 Answers2

1

there's no relation with iteration, previous or next elements.

The real issue is that your start and end points aren't tuples but None. So the first thing that does this code:

for previous, current, nxt in previous_and_next(sortedlist):
       if previous[1] > current[1] and nxt[1] > current[1]:
           UF.insert_objects(current)

is breaking because previous is None and None[1] isn't valid (not subscriptable).

>>> previous=None
>>> previous[1]
Traceback (most recent call last):
  File "<string>", line 301, in runcode
  File "<interactive input>", line 1, in <module>
TypeError: 'NoneType' object is not subscriptable

So either replace None by a tuple made of "invalid" values (like (-1,-1), depending on the effect you need) or filter out start & end triplets:

for t in previous_and_next(sortedlist):
    if None not in t:
       previous, current, nxt = t 
       if previous[1] > current[1] and nxt[1] > current[1]:
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
0

Not sure I understand your question, but think maybe this might help:

def previous_and_next(iterable):
    iterable = iter(iterable)

    prv, cur, nxt = None, next(iterable), next(iterable)
    while True:
        yield prv, cur, nxt
        prv, cur, nxt = cur, nxt, next(iterable)


tuples = [(1, 1), (2, 2), (3, 4), (4, 3), (5, 5), (6, 3.5), (7, 7), (8, 8), (9, 9),
          (10, 8), (11, 9.5), (11, 7.5), (12, 12), (13, 1.5)]

for p, c, n in previous_and_next(tuples):
    print(p, c, n)

Output:

None (1, 1) (2, 2)
(1, 1) (2, 2) (3, 4)
(2, 2) (3, 4) (4, 3)
(3, 4) (4, 3) (5, 5)
(4, 3) (5, 5) (6, 3.5)
(5, 5) (6, 3.5) (7, 7)
(6, 3.5) (7, 7) (8, 8)
(7, 7) (8, 8) (9, 9)
(8, 8) (9, 9) (10, 8)
(9, 9) (10, 8) (11, 9.5)
(10, 8) (11, 9.5) (11, 7.5)
(11, 9.5) (11, 7.5) (12, 12)
(11, 7.5) (12, 12) (13, 1.5)
martineau
  • 119,623
  • 25
  • 170
  • 301