Removing consecutive occurrences from end of list python

I have a numpy array:

ar = np.array([True, False, True, True, True])

If the last element is True, I want to remove all of the consecutive true elements at the end of the array. So for example

magic_func(ar) => [True, False]

If ar = [True, False, True, False, True] . Then

magic_func(ar) => [True, False, True, False]

If ar = [True, False, False] , the function does nothing, because the last element is False

Is there a one liner in python to do this? using a numpy library or something


This one line function should work, but looks very nasty and probably not efficient lol. Basically the idea is to find the most right False and return all values before False

def magic_func(a):
    return a[:len(a)-np.where(a[::-1]==False)[0][0]] if np.where(a[::-1]==False)[0].size>0 else a[:0]

>>> a = np.array([False, True, True, True, True])
>>> magic_func(a)
array([False], dtype=bool)

Use itertools.dropwhile and np.fromiter like this.

from itertools import dropwhile
np.fromiter(dropwhile(lambda x: x, ar[::-1]), dtype=bool)[::-1]

Edit

This is more faster way.(Just use itertools.takewhile )

from itertools import takewhile
ar[:-sum(1 for i in takewhile(lambda x: x, reversed(ar)))]

Time:

ar = np.array([True, False, True, True, True])

#mine
%timeit ar[:-sum(1 for i in takewhile(lambda x: x, reversed(ar)))]
1000000 loops, best of 3: 1.84 us per loop

#mine
%timeit np.fromiter(dropwhile(lambda x: x, ar[::-1]), dtype=bool)[::-1]
100000 loops, best of 3: 2.93 us per loop

#@Jaime
%timeit ar[np.bitwise_or.accumulate(~ar[::-1])[::-1]]
100000 loops, best of 3: 3.63 us per loop

#@askewchan
%timeit ar[:len(ar)-np.argmin(ar[::-1])]
100000 loops, best of 3: 6.24 us per loop

#@xbb
%timeit ar[:len(ar)-np.where(ar[::-1]==False)[0][0]] if np.where(ar[::-1]==False)[0].size>0 else ar[:0]
100000 loops, best of 3: 7.61 us per loop

PS:

This is no-magic function.

def no_magic_func(ar):
    for i in xrange(ar.size-1, -1, -1):
        if not ar[i]:
            return ar[:i+1]
    return ar[0:0]

Time:

ar = np.array([True, False, True, True, True])

%timeit no_magic_func(ar)
1000000 loops, best of 3: 954 ns per loop

This is a little too magic for my liking, but it does seem to work nicely:

>>> ar = np.array([True, False, True, True, True])
>>> ar[np.bitwise_or.accumulate(~ar[::-1])[::-1]]
array([ True, False], dtype=bool)

To understand what's going on, first we negate the array, turning the True s into False s and viceversa, then we reverse the order, then we accumulate the result of OR-ing the array: this will be False until the first True , and will remain True thereafter. reversing this array, we have a boolean indexing array that will get rid of all trailing True s.

链接地址: http://www.djcxy.com/p/78734.html

上一篇: 的node.js

下一篇: 从列表末尾删除连续的事件