using a single line to filter out digits from string python

Viewed 931

I am refactoring my code so that it is done in a more pythonic way. Specifically I have a section that is returning tokens from a string if that token is not an integer. Initially I wrote the function as follows

 string = "these 5 sentences should not have 2 numbers in them"
 newString = []
 for token in string.split():
     if token.isdigit() == False:
         newString.append(token)
 newString = " ".join(newString)
 print(newString)

While this works I wont to make the code look less clunky. So I rewrote it as follows

   newString = [token for token in string.split() if token is not 
   token.isdigit() ]

But this does not seem to catch the digits. Why is the lambda expression not working ?

5 Answers

try this:

string = "these 5 sentences should not have 2 numbers in them"

newString = " ".join(token for token in string.split() if not token.isdigit())

print(newString)

the problem was the use of is.

although python is very similar to English sometimes, which is great, in some cases it causes confusion :)

is is an identity comparison operator,

quoting the docs:

The operators is and is not test for an object’s identity: x is y is true if and only if x and y are the same object. An Object’s identity is determined using the id() function. x is not y yields the inverse truth value.

it tried to see if token (which is some string) is not token.isdigit() (which is some boolean), this is of course true for all tokens :)

In your code you are comparing token and token.isdigit() with is not operator. It compares objects if they are the same object, but string and boolean are not even the same type, so outcome is always true:

>>> string = "these 5 sentences should not have 2 numbers in them"
>>> string.split()
['these', '5', 'sentences', 'should', 'not', 'have', '2', 'numbers', 'in', 'them']
>>> token = string.split()[3]
>>> token
'should'
>>> token.isdigit()
False
>>> token is not token.isdigit()
True
>>> token = string.split()[1]
>>> token
'5'
>>> token is not token.isdigit()
True

So you should just drop token is from your code and it should be fine.

This code is working, I just tried it.

newString = " ".join([x for x in string.split() if x.isdigit() == False])

Check it.

All things in one line of code only.

Something like:

newstring = ''.join(map(lambda x: x if not x.isdigit() else "", string.split() ))

exactly with spaces:

newstring = ' '.join(map(lambda x: x if not x.isdigit() else "", string.split() )).replace('  ', ' ')

Alternative solution using filter(), perhaps slightly shorter:

newString = ' '.join(filter(lambda s: not s.isdigit(), string.split()))

Related