Générer une représentation de chaîne d'un encodage d'un chaud
-
20-09-2019 - |
Question
En Python, je dois générer une dict
qui associe une lettre à un « pré-défini un chaud » représentation de cette lettre. A titre d'illustration, le dict
devrait ressembler à ceci:
{ 'A': '1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0',
'B': '0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0', # ...
}
Il y a un bit (représenté comme un caractère) par lettre de l'alphabet. Par conséquent chaque chaîne contiendra 25 zéros et un 1. La position du 1
est déterminée par la position de la lettre correspondante dans l'alphabet.
Je suis venu avec un code qui génère ceci:
# Character set is explicitly specified for fine grained control
_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
n = len(_letters)
one_hot = [' '.join(['0']*a + ['1'] + ['0']*b)
for a, b in zip(range(n), range(n-1, -1, -1))]
outputs = dict(zip(_letters, one_hot))
Y at-il un moyen plus efficace / propre / plus pythonique à faire la même chose?
La solution
Je trouve cela plus lisible:
from string import ascii_uppercase
one_hot = {}
for i, l in enumerate(ascii_uppercase):
bits = ['0']*26; bits[i] = '1'
one_hot[l] = ' '.join(bits)
Si vous avez besoin d'un alphabet plus général, énumérer un peu plus d'une chaîne de caractères, et remplacer ['0']*26
avec ['0']*len(alphabet)
.
Autres conseils
En Python 2.5 et jusqu'à vous pouvez utiliser l'opérateur conditionnel:
from string import ascii_uppercase
one_hot = {}
for i, c in enumerate(ascii_uppercase):
one_hot[c] = ' '.join('1' if j == i else '0' for j in range(26))
one_hot = [' '.join(['0']*a + ['1'] + ['0']*b)
for a, b in zip(range(n), range(n-1, -1, -1))]
outputs = dict(zip(_letters, one_hot))
En particulier, il y a beaucoup code emballé dans ces deux lignes. Vous pouvez essayer Présentez Expliquer variable refactoring. Ou peut-être un méthode d'extraction .
Voici un exemple:
def single_onehot(a, b):
return ' '.join(['0']*a + ['1'] + ['0']*b)
range_zip = zip(range(n), range(n-1, -1, -1))
one_hot = [ single_onehot(a, b) for a, b in range_zip]
outputs = dict(zip(_letters, one_hot))
Bien que vous pourriez être en désaccord avec ma nomination.
Cela semble assez clair, concis et Pythonic pour moi.