Ryan Sayles
Ryan Sayles

Reputation: 3441

Shortening a list

I have a simple question that I can't seem to find the answer to. I have a list in python that I want to make shorter based on the values at the end. For example say I have list = [0,0,1,2,1,2,2,2,0,1,1,0] I want to remove any 0's that are at the end or beginning of the list so this translates into list = [1,2,1,2,2,2,0,1,1]. I tried using filter() but this is removing all instances of 0 when I just want to remove the ends. I'm new to python and can't seem to figure this out. Any help would be appreciated!

Upvotes: 2

Views: 912

Answers (6)

inspectorG4dget
inspectorG4dget

Reputation: 114035

In [88]: L = [0,0,1,2,1,2,2,2,0,1,1,10,0]

In [89]: s = ','.join(str(i) for i in L)

In [90]: while s[-2:] == ',0':
   ....:     s = s[:-2]
   ....:     

In [91]: while s[:2] == '0,':
   ....:     s = s[2:]
   ....:     

In [92]: [int(i) for i in s.split(',')]
Out[92]: [1, 2, 1, 2, 2, 2, 0, 1, 1, 10]

Better yet:

In [102]: L = [0,0,1,2,1,2,2,2,0,1,1,10,0]

In [103]: blacklist = set()

In [104]: mid = False

In [105]: for i,num in enumerate(L):      
    if not mid and not num:
        blacklist.add(i)
    elif num:
        mid = True

In [106]: mid = False

In [107]: for i,num in enumerate(reversed(L)):
    if not mid and not num:
        blacklist.add(len(L)-i)
    elif num:
        mid = True

In [108]: [num for i,num in enumerate(L) if i not in blacklist]
Out[108]: [1, 2, 1, 2, 2, 2, 1, 1, 10]

Upvotes: 0

kojiro
kojiro

Reputation: 77197

Edit: I like this approach better:

def trim(lst, key=lambda i:i==0):
  g = [(k,list(group)) for k, group in groupby(lst, key=key)]
  if g[0][0]: del g[0]
  if g[-1][0]: del g[-1]
  return list(chain.from_iterable(group[1] for group in g))

Original:

The left trim can be handled very handily with itertools, but itertools isn't quite as good with the ends of lists.

def ltrim(lst, v=0):
  return list(itertools.dropwhile(lambda i:i==v, lst))

def rtrim(lst, v=0):
  return reversed(ltrim(reversed(lst), v))

def trim(lst, v=0):
  return ltrim(rtrim(lst, v), v)

Upvotes: 1

Jon Clements
Jon Clements

Reputation: 142256

You could do something like:

from itertools import takewhile
def list_strip(sequence, item):
    leading = sum(1 for el in takewhile(lambda L: L == item, sequence))
    trailing = sum(1 for el in takewhile(lambda L: L == item, reversed(sequence)))
    slc = slice(leading, -trailing or None)
    return sequence[slc]

Upvotes: 3

Lelouch Lamperouge
Lelouch Lamperouge

Reputation: 8421

May not be most efficient, but one way is

>>> myList
[0, 0, 1, 2, 1, 2, 2, 2, 0, 1, 1, 0]
>>> [int(str_element) for str_element in "".join(str(int_element) for int_element in myList).strip('0')]
[1, 2, 1, 2, 2, 2, 0, 1, 1]

Upvotes: 0

FoggyDew
FoggyDew

Reputation: 211

you can use pop method: L.pop([index]) -> item -- remove and return item at index (default last). Raises IndexError if list is empty or index is out of range.

Upvotes: 0

Adam Spiers
Adam Spiers

Reputation: 17936

while list[0] == 0:
   list.pop(0)
while list[-1] == 0:
   list.pop()

but it's best not to use a variable named list because that overrides the built-in list type.

Upvotes: 6

Related Questions