Executando verificação de segurança...
1

Muito obrigado pelas dicas.
A ideia de usar um método de limpeza que englobe tantos caracteres me veio depois de um cliente precisar persisdir dados de clientes em um bando de dados usando extensos arquivos xlsx gerados por outro sistema. Não sei o porque mas esses relatórios gerados, além de gerar dados bagunçados, ainda gerava saídas com caracteres estranhos e indesejáveis em meio aos dados.
Tentei usar regex para selecionar somente os números, mas mesmo assim não tive êxito.
Ah, e como os arquivos xlsx do cliente tinham muitos dados, com reduce consegui um certo desempenho melhorado, nada tão melhor assim, mas no final melhorou.
Vou aplicar sua ideia de realizar o cálculo dos dígitos em um único momento.
Forte abraço.

2

Embora seja possível com regex, acho desnecessário. O loop que sugeri acima é bem mais simples, além de ser mais rápido. Fiz um teste básico pra verificar:

import string, re
from timeit import timeit

r = re.compile('[0-9]')
string_chain = '123@#$%456&*()789-09'

# executa 1 milhão de vezes cada teste
params = { 'number' : 1000000, 'globals': globals() }

# imprime os tempos em segundos
# todos retornam uma lista com os dígitos já convertidos para int

# loop simples
print('          loop:', timeit('list(int(c) for c in string_chain if c in string.digits)', **params))

# loop simples, usando um set com os dígitos (ligeiramente mais rápido)
digitos = set(string.digits)
print('  loop com set:', timeit('list(int(c) for c in string_chain if c in digitos)', **params))

# regex finditer (o mais lento)
print('regex finditer:', timeit('list(int(c[0]) for c in r.finditer(string_chain))', **params))

# regex findall (o segundo mais lento)
print(' regex findall:', timeit('list(int(c) for c in r.findall(string_chain))', **params))

Os tempos exatos variam de acordo com o hardware, mas de forma geral, regex foi o mais lento. Na minha máquina o resultado foi (tempos em segundos, quanto menor, mais rápido):

          loop: 2.2100358860002416
  loop com set: 1.788499561000208
regex finditer: 3.175833621000038
 regex findall: 2.61522052600003

Claro que para poucas strings pequenas, a diferença será imperceptível. Mas se tiver milhões de strings para validar, começa a fazer diferença.