-4

For example, I have a array X [1, 3, 2, 5, 1, 3], I need a new array like a moving window, find the smallest in every 3 items ==> [1, 1, 1, 2, 1, 1]

I know I can loop from array len() and use list slip, but Is there a pythonic way for this problem?

I tried X[1] and found type(X[1]) is a int and cannot trace back the the array X.

Thank you for your help.

edited: sorry for the inconvenient. i made a mistake above. for window 1, only the first element 1, so output 1 window 2: [1,3] -> 1 window 3: [1, 3, 2] -> 1 window 4: [3, 2, 5] -> 2

btw the anwsers is very helpful. thank you.

football
  • 19
  • 4

4 Answers4

1
map(min, zip(a[1:]+[max(a)], [max(a)]+a, a+[max(a)]))

I don't know if it is a pythonic way. It's just a tricky one-liner and is not preferable to ordinary loop.

Liteye
  • 2,761
  • 1
  • 16
  • 16
1
In [33]: X = [1, 3, 2, 5, 1, 3]

In [34]: list(map(min, (X[i:i+3] for i in range(len(X)-2))))
Out[34]: [1, 2, 1, 1]
inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
  • This does not yield the expected output in the question. Maybe the OP wanted something different, you should wait untile he/she clarifies. – Stefano Sanfilippo May 10 '14 at 14:22
  • 1
    @StefanoSanfilippo: I already commented, asking for clarification from OP. Since OP seems unresponsive to comments on the question itself, I figured I'd give it a shot, hoping to hit something close to what OP is looking for – inspectorG4dget May 10 '14 at 14:28
  • @inspectorG4dget Thanks a lot, that's what I need. and I hope the window rolls from the first and single element, I'll solve this. – football May 12 '14 at 04:58
  • @StefanoSanfilippo Thank you, I made a mistake in OP. the third number should be 1. I've updated it. – football May 12 '14 at 05:05
0
def pairwise( iterable, n=2 ):
    from itertools import tee, izip, islice
    return izip(*(islice(it,pos,None) for pos,it in enumerate(tee(iterable, n))))

 x = [1, 3, 2, 5, 1, 3]


list(pairwise(x,3))
#[(1, 3, 2), (3, 2, 5), (2, 5, 1), (5, 1, 3)]
map(min, pairwise(x,3))
#[1, 2, 1, 1]
M4rtini
  • 13,186
  • 4
  • 35
  • 42
0
history = collections.deque((None, None), 2)  # sentinel
for x in your_input:
    result = min(x, min(history))
    history.append(x)

Choice of sentinel depends on how you want to treat start of input.

Or if this is clearer

window = collections.deque((), 3)
for x in your_input:
    window.append(x)
    result = min(window)

First uses explicit history as OP subject, last explicit window.

deque with size argument automatically drops off elements from the other end on append when size is exceeded.

Dima Tisnek
  • 11,241
  • 4
  • 68
  • 120