0

For now I have an object of list like this:

lst = [None, None, 'one', None, 'two', None]

I am trying to perform strip() on it and get a result like this:

strip(lst)

>> ['one', None, 'two']

left_strip(lst)

>> ['one', None, 'two', None]

Is there a graceful way of doing that?

ps: thanks 4 @woockashek's advice, I've changed the lst
From [None, None, 'one','two', None] To [None, None, 'one', None, 'two', None]

DeFOX
  • 86
  • 1
  • 8
  • Not a single solving attempt, just a question dump and this one has an upvote? Cool voting. – Lafexlos Nov 09 '16 at 13:14
  • 1
    It's not clear now what you would like to achieve. What about `[None, 'one', None, 'two', None]`. You expect `['one', None, 'two']` or `['one', 'two']`? – woockashek Nov 09 '16 at 13:24

8 Answers8

7

To get a behaviour like left_strip you will need to import dropwhile from itertools:

>>> lst=[None, None, 'one', None, 'two', None, None]
>>> from itertools import dropwhile
>>> def left_strip(lst):
        return list(dropwhile(lambda x : x is None, lst))
>>> left_strip(lst)
['one',None, 'two', None, None]

To get a behaviour like right_strip:

>>> from itertools import dropwhile
>>> def right_strip(lst):
        return list(reversed(left_strip(reversed(lst))))
>>> right_strip(lst)
[None, None, 'one', None, 'two']

To get strip run both in sequence:

>>> left_strip(right_strip(lst))
['one', None, 'two']
Sebastian Wozny
  • 16,943
  • 7
  • 52
  • 69
5

You could use itertools.dropwhile to emulate an lstrip:

def lstrip(list):
    return list(itertools.dropwhile(lambda x : x is None, list))

lst = [None, None, 'one', 'two', None]
lstrip(lst)
>> ['one', 'two', None]

rstrip could be implemented in the same way, but reversing the list before and after using dropwhile

def rstrip(list):
    return list(reversed(lstrip(reversed(list))))
tehforsch
  • 316
  • 1
  • 4
1

there's a filter method:

lst = filter(None, lst)

But it will also remove 0 values if you have them on your list

To fix this behaviour you have to write your own filter method

def FilterNone(arg):
    return arg is not None

filtered_list = filter(FilterNone, lst)
woockashek
  • 1,588
  • 10
  • 25
  • This is not correct answer. What if You pass `lst = [None, 1, None, 2, None]`? – Fejs Nov 09 '16 at 13:31
  • Example is unclear so I assumed that this situation will never occur. I also asked about such example in OP's post but didn't get answer. – woockashek Nov 09 '16 at 13:38
  • If You know what `string.strip()` does (removes empty spaces from both ends), You can assume that this is desired behavior (or course, You need to strip `None` here). – Fejs Nov 09 '16 at 13:42
  • I try to read between the lines. Mentioning about `strip` doesn't guarantee that user needs its exact behaviour, that's why I'm waiting for his update. – woockashek Nov 09 '16 at 13:50
1

you can use the filter like that:

lst = [None, None, 'one', 'two', None]
list(filter(None.__ne__, lst))
omri_saadon
  • 10,193
  • 7
  • 33
  • 58
  • This one gives `AttributeError: 'NoneType' object has no attribute '__ne__'` on python2.7, so It's probably a python3 solution – woockashek Nov 09 '16 at 13:12
  • This is not correct answer. What if You pass `lst = [None, 1, None, 2, None]`? Also, You don't have solution for `left_strip`. – Fejs Nov 09 '16 at 13:32
1

Here is a natural left_strip():

def left_strip(items):
    for i,x in enumerate(items):
        if x is not None: return items[i:]
    return [] #in case all are None

For example,

>>> left_strip(lst)
['one', 'two', None]
John Coleman
  • 51,337
  • 7
  • 54
  • 119
0

You can try:

def left_strip(lst):
    for i, e in enumerate(lst):
        if e is not None:
            return lst[i:]
    return []


def right_strip(lst):
    for i, e in reversed(list(enumerate(lst))):
        if e is not None:
            return lst[:i+1]
    return []

print left_strip(right_strip(lst))

You can read more in remove None value from a list without removing the 0 value

Community
  • 1
  • 1
daniboy000
  • 1,069
  • 2
  • 16
  • 26
  • 1
    First, You don't have answer for second function (`left_strip`). Second, this answer is not correct. What if You have `None` between `1` and `2`? – Fejs Nov 09 '16 at 13:24
0

Did not get what you actually want to do ? You can use lst[2:4] and lst[2:].

Update: use set

if you want to have only values which are not 'None' then you use set as shown:

lst = [None, None, 'one', 'two', None]
lst1=[None]
print list(set(lst)-set(lst1))
Biswal
  • 53
  • 7
  • This answer is not correct unless You have exactly this input. Which is terrible assumption to make. – Fejs Nov 09 '16 at 13:29
  • @Fejs I have indicated that it is unclear what is asked. Answer is based on the assumption of left strip. – Biswal Nov 09 '16 at 14:16
0

One way of doing it is:

def right_strip(lst):
    for i in range(len(lst) - 1, -1, -1):
        if lst[i] != None:
            break
    else:
        return []
    return lst[:i + 1]

def left_strip(lst):
    for i in range(len(lst)):
        if lst[i] != None:
            break
    else:
        return []
    return lst[i:]

def strip(lst):
    return left_strip(right_strip(lst))
Fejs
  • 2,734
  • 3
  • 21
  • 40