迅速かつポータブルソリューション:
from zlib import crc32
def bytes_to_float(b):
return float(crc32(b) & 0xffffffff)/2**32
これは、0.0と1.0の間のfloatにバイト文字列に変換します。あなたは(のpython 3で例えば、)Unicode文字列を使用している場合は、それをエンコードする必要があります。
def str_to_float(s, encoding="utf-8"):
return bytes_to_float(s.encode(encoding))
例
>>> str_to_float(u"café")
0.5963937465567142
これは、任意のマシン上で同じ結果を与え、任意の必要がありますPythonのバージョン(Python 2.7と3.5でテスト済み)。
注:& 0xffffffff
は、符号なしのint結果を保証するためのものです。これは、Pythonバージョンcrc32(b)
に応じて、符号付きまたは符号なしintを返す可能性があるため必要です。
編集
あなたはCRC32よりも "ランダム" 何かが、あなたがそのようなSHA256として、代わりにハッシュ関数を使用することができますしたい場合:
from struct import unpack
from hashlib import sha256
def bytes_to_float(b):
return float(unpack('L', sha256(b).digest()[:8])[0])/2**64
性能試験
String length
Function 7 70 700 7000
b2f_crc32 0.34 0.38 0.87 5.59
b2f_md5 0.96 1.08 2.11 11.13
b2f_sha1 0.99 1.07 1.76 8.37
b2f_sha256 1.11 1.20 2.60 16.44
b2f_rnd 6.59 6.55 6.59 6.60
基本的に、CRC32ソリューションは短い文字列ではるかに高速です(@ user3030010のランダム= RND解)。文字列の長さに関係なく、SHA256より約3倍高速です。 SHA256はMD5よりも遅く、SHA1よりも遅い(非常に短い文字列を除く)。しかし、RNDオプションは文字列の長さに依存しないので、文字列が非常に長い場合は、最も速いオプションになります(ただし、@ user3030010の答えを参照してください)。私のコンピュータでは、2500より長い文字列に対してSHA256 8000文字以上の文字列に対してはCRC32よりも優れています。ここで
がtimeit.timeit()
を使用して、コードです:
from __future__ import print_function
[...] # define b2f_crc32, b2f_md5 and so on.
for func in ("b2f_crc32", "b2f_md5", "b2f_sha1", "b2f_sha256", "b2f_rnd"):
for length in (7, 70, 700, 7000):
t = timeit('b2f(b"%s")'%(b"x"*length),
'from __main__ import %s as b2f' % func)
print("%.2f"%t, end="\t")
print()
私はよく理解していれば、random.seed()のみジェネレータを初期化しますが、何も返しませんか? – Vincent
@Vincentそれは正しいです。しかし、 'random.random()'によって返される値の順序に影響します。したがって、最初の乱数は種に直接依存します。 – Barmar
この答えは興味深いですが、2つの制限があります。まず、 'hash'がPythonインストールで異なる結果を返す可能性があるため、Pythonのインストールによって異なる結果が返される可能性があります。第2に、共有ランダムシードを変更するので、プログラムの他の部分が乱数に依存する場合、これは悪い副作用を有する可能性があります。私は自分の答えを推奨するか、少なくとも 'random.seed(hash(your_string))'を 'rnd = random 'に置き換えることを推奨します。ランダム(your_string) '、次に' rnd.random() 'です。 – MiniQuark