Python で文字列を固定幅 Unicode UCS-2 にエンコードする

okwaves2024-01-25  10

固定幅の文字列エンコーディングが必要です。私が理解したところによると、UCS-2 と UCS-4 (ASCII) はそのような固定幅エンコーディングです。

私が理解したところによると、Python は s.encode('utf_16_le') を介した可変幅 UTF-16 のみをサポートしています。本当ですか? Unicode 固定幅エンコードにエンコードする簡単な方法はありますか?

コンテキスト: 文字列配列を生のバイトで保存しているため、元の文字列を復元するためにインデックスを付ける方法が必要です。すべての文字が固定幅の場合、インデックスの計算が簡単になります。

strings = ['asd', 'def']

# ascii
bytelens = list(map(len, strings))
bytes = ''.join(strings).encode('ascii')

# utf8
bytelens = []
bytes = bytearray()
for s in strings:
  e = s.encode('utf-8')
  bytelens.append(len(e))
  bytes.extend(e)

# i need bytelens to later recover original strings from the array bytes

ご覧のとおり、ASCII バリアントは非常に単純ですが、UTF-8 はより複雑で 20% 遅くなります (おそらく、多くの割り当てと関数呼び出しが原因です)。真の固定幅 UCS-2 が解決策となります。

追加の質問: 文字列に UCS の文字が含まれているかどうかを確認するにはどうすればよいですか?-1 / UCS-2 / UCS-4? UCS-1 の場合は str.isascii があります。 UCS-2 について何かアイデアはありますか?

なぜバイトを扱いたいのですか?

– 素晴らしい雨

2020 年 9 月 3 日 11:48

その後、バイトを PyTorch テンソルにロードして、マルチプロセッシング データ ローダー スレッド間で共有するためです: context in github.com/pytorch/pytorch/issues/13246

– ヴァディム・カントロフ

2020 年 9 月 3 日 11:51



------------------------

さまざまな概念を組み合わせています。

Python では、文字列 (または配列) にインデックスを付けるだけです。各文字の長さは関係ありません。ただし、この場合も、1 つの文字が単一の単純なエンティティではないことを警告する必要があります。単一のエンティティが必要な場合は、より多くの文字をまとめる必要があります (アクセント記号などの文字を組み合わせます)。

UTF16 は可変幅ですが、UCS2 と同じですが、UCS2 の外の文字に対応します。したがって、ほとんどの場合、それは問題ではなく、そのような文字がある場合は、時々低位および高位のサロゲートを操作するだけです (他の多くの com と同様)puter 言語 (UCS2 のみをサポート)。ただし、文字列はランダムな場所で分割するのではなく、常にエンティティの最後で分割する必要があるため、これは多くの場合問題になりません。

UCS4 と UTF-32 は実質的に同じエンコーディングです。Unicode コードは 32 ビット数値を指します。 (違いは仮想的なものであり、いくつかの定義に基づくものであり、Unicode 文字の場合ではありません [UCS は、より多くの (より高い) コードポイントを許可する ISO に基づいており、割り当てられることはありません)

10

" Python では、文字列 (または配列) にインデックスを付けるだけです。長さは関係ないすべての文字の th です。」 1 つの大きな PyTorch バイト配列にインデックスを付けてから、個々の文字列を復元します。これは、共有メモリの問題を回避するために行われます。私のキャラクターがすべて UCS-2 に適合していることを確認する方法はありますか?例えば。すべての文字が厳密に 2 バイトとしてエンコードされることを (迅速な方法で) 確認したいと考えています。一部の文字が 1 バイトで表され、一部の文字が 2 バイトで表される状況は避けたいと考えています。これにより、インデックスの計算が中断されます。

– ヴァディム・カントロフ

2020 年 9 月 3 日 12:16

UTF-16 でエンコードされたバイト長を回復する方法があれば、私の問題も解決されるでしょう。

– ヴァディム・カントロフ

2020 年 9 月 3 日 12:21

私の理解が正しければ、1) すべての文字が UCS-2 に適合することを確認し、2) バイトレンズを [len(s) * 2 for s in strings] として計算できるはずですよね。 str.isascii が存在することは知っています。 str.isucs2はありますか?見つかりませんでした。また、すべての文字を反復処理すると時間がかかる可能性があります。

– ヴァディム・カントロフ

9月2020 年 3 月 12:32

最初の質問については、バイトの読み取り方法によって異なります。 Python 文字列は「固定」文字列を使用します。長さのエンコーディング。可変の場合があります。言い換えれば、文字列内のすべての文字は同じ長さですが、文字列が単なる ASCII [または Latin1] の場合、Python は 1 バイトだけを使用し、UCS2 を使用できる場合は UCS2 を使用し、それ以外の場合は UTF-32 を使用します。 。すべての文字列は異なる「サブエンコーディング」を使用できますが、文字列内のすべての文字の長さは同じです。

– ジャコモ・カテナッツィ

2020 年 9 月 3 日 12:39

文字列は読み取り専用であるため、問題が発生することはありません。 [新しい文字列を生成することなく、文字列の途中で文字を変更することはできません]

– ジャコモ・カテナッツィ

2020 年 9 月 3 日 12:39

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。