Greetings!
It is probably an elementary problem for you but I'm struggling to understand why the snippet below is failing.
I found it online and it looks ok, but it is not.
s = 'November 11 day'
pp = int(filter(str.isdigit, s))
print(f" Digits only -> {pp}")
error:
"int() argument must be a string, a bytes-like object or a number, not 'filter'"
if anyone would explain to me why it errors out...
Thank you!
filter() returns a filter object, which is iterable. According to the documentation
https://docs.python.org/3/library/functions.html#filter
Quote:filter(function, iterable)
Construct an iterator from those elements of iterable for which function returns true. iterable may be either a sequence, a container which supports iteration, or an iterator. If function is None, the identity function is assumed, that is, all elements of iterable that are false are removed.
Note that filter(function, iterable) is equivalent to the generator expression (item for item in iterable if function(item)) if function is not None and (item for item in iterable if item) if function is None
You could do "".join(filter(str.isdigit, s)).
s = 'November 11 day'
pp = int("".join(filter(str.isdigit, s)))
print(f" Digits only -> {pp}")
I don't think you can int the filter object, that's the problem
This will give you a list of individual digits:
pp = list(filter(str.isdigit, s))
If you want integers:
def makeInt(alist):
for i in range(len(alist)):
num = int(alist[i])
alist[i] = num
return alist
print(f" Digits only -> {makeInt(pp)}")
But if you want to find numbers, use a regex:
import re
pattern = re.compile('[0-9]+')
result = re.findall(pattern, s)
result_integers = makeInt(result)
print(f" numbers only -> {makeInt(result)}")
Awesome! Thank you for coaching! You guys(girls?) are the best!
Thank you!
There are excellent asnswers to your problem already. Just some additional tidbits.
You can apply int using built-in function map or list comprehension:
>>> s = 'November 11 day'
>>> print(*map(int, filter(str.isdigit, s)))
1 1
>>> [int(i) for i in filter(str.isdigit, s)]
[1, 1]
If you want to have numbers and not digits one way is to use groupby from itertools:
>>> from itertools import groupby
>>> [int(''.join(group)) for num, group in groupby(s, key=str.isdigit) if num]
[11]
>>> s = 'November 11 day 2022 year'
>>> [int(''.join(group)) for num, group in groupby(s, key=str.isdigit) if num]
[11, 2022]
Beware that not all values passing str.isdigit are convertible to int:
>>> s = '1²'
>>> s.isdigit()
True
>>> int(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '1²'
Using regular expressions
>>> import re
>>> s = '1918 November 11 day'
>>> int(re.sub(r'[^\d]+', '', s) or '0')
191811
>>>