When you have capture groups (wrapped with parentheses) in the regular expression, it findallwill return a match for the captured group; And in your case, the captured group corresponds to an empty string; You can do this without grabbing with ?:if you want to return the entire match; re.searchignores capture groups, on the other hand. They are reflected in the documentation:
re.findall:
, . , . , ; , .
re.search:
, , MatchObject. , ; , - .
import re
reg = re.compile(r'^\d{1,3}(?:,\d{3})*$')
s = '42'
reg.search(s).group()
reg.findall(s)