3

在 Python 中,我需要生成一个dict将一个字母映射到该字母的预定义“ one-hot ”表示。举例来说,dict应该如下所示:

{ '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', # ...
}

字母表中的每个字母都有一位(表示为一个字符)。因此,每个字符串将包含 25 个零和一个 1。 的位置1由字母表中相应字母的位置决定。

我想出了一些生成此代码的代码:

# 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))

是否有更高效/更清洁/更 Pythonic 的方式来做同样的事情?

4

4 回答 4

7

我发现这更具可读性:

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)

如果您需要更通用的字母表,只需枚举一串字符,然后替换['0']*26['0']*len(alphabet).

于 2009-10-10T20:40:29.183 回答
2

在 Python 2.5 及更高版本中,您可以使用条件运算符:

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))
于 2009-10-10T21:13:39.943 回答
1
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))

特别是,这两行中包含了大量代码。您可以尝试Introduce Explaining Variable重构。或者也许是一种提取方法

这是一个例子:

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))

虽然你可能不同意我的命名。

于 2009-10-10T20:36:44.467 回答
-1

这对我来说似乎非常清晰、简洁和 Pythonic。

于 2009-10-10T20:23:28.080 回答