omer bach
omer bach

Reputation: 2395

What is the most pythonic way to filter list from number?

i have this :

['SPRD', '60', 'p25']

I want to generate that :

['SPRD', 'p']

What is the most pythonic way to do that?

Thanks.

Upvotes: 2

Views: 161

Answers (7)

Rafael Barbosa
Rafael Barbosa

Reputation: 1190

According to a previous answer, casting should be faster and "prettier" than regex or string operations.

The best way to do this then should look something like this:

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

#with list comprehension
def filter_number(seq):
    return [item for item in seq if not is_number(item)]

#with a generator
def filter_number_generator(seq):
    for item in seq:
        if not is_number(item): yeld item

If your goal is to have a copy of the list in memory, you should use the list comprehension method. Now if you want to iterate over each non-number item in the list efficiently, the generator allows you to do something like:

for non_number in filter_number_generator(l)

Upvotes: 0

root
root

Reputation: 80346

In [25]: l = ['SPRD', '60', 'p25']

In [26]: filter(None,(s.translate(None,'1234567890') for s in l))
Out[26]: ['SPRD', 'p']

Upvotes: 3

glormph
glormph

Reputation: 1004

If your lists only contain strings and you only want to filter out numbers, this, however clunky, may work too:

def filter_text(x):
    try:
        int(x)
        return ''
    except ValueError:
        return x

l = ['SPRD', '60', 'p25']
newlist = []
for x in l:
     newlist.append(''.join([filter_text(y) for y in x]))
newlist = [x for x in newlist if x != '']

Upvotes: 0

user1444165
user1444165

Reputation:

import re
filter(None, [re.sub("\d+", "", f) for f in input_list])

I believe this is quite pythonic, although it does require regex and is not as efficient as other answers. First, all digits are removed from words, then any emptystrings are removed from the list.

Upvotes: 1

Amber
Amber

Reputation: 526573

digits_stripped = (s.translate(None, '0123456789') for s in input_list)
without_blanks = [s for s in digits_stripped if s]

(Note that if you happen to be using a Python older than 2.6, you'll need to use string.maketrans('', '') instead of None as the first argument to translate().)

Upvotes: 4

dmeister
dmeister

Reputation: 35614

Use a generation expression, regular expressions, a list comprehensions:

import re
[s for s in (re.sub("[0-9]*", "", s) for s in l) if s]

Upvotes: 0

avasal
avasal

Reputation: 14854

In [37]: l = []

In [38]: p = "[a-zA-Z]*"

In [39]: p1 = re.compile(p)

In [40]: for i in  ['SPRD', '60', 'p25']:
   ....:     if p1.match(i):
   ....:         l.append(p1.match(i).group())
   ....:

In [41]: [x for x in l if x]
Out[41]: ['SPRD', 'p']

Upvotes: 1

Related Questions