use*_*014 5 python random hash python-3.x
我需要找到一个随机颜色,给定一个特定的种子号 - 快。两次给出相同的 ID,应该返回相同的颜色。
我这样做了:
def id_to_random_color(number):
random_bytes = hashlib.sha1(bytes(number)).digest()
return [int(random_bytes[-1]) / 255, int(random_bytes[-2]) / 255, int(random_bytes[-3]) / 255, 1.0]
Run Code Online (Sandbox Code Playgroud)
问题是多次计算数字的 sha1 总的来说非常慢。(我使用这个功能大约 10 万次)
编辑:我使用散列函数的原因是我希望对于接近的数字使用不同的颜色
例如id_to_random_color(7)应该与id_to_random_color(9)
使用带有静态变量的简单随机数生成器可以提高性能:
import random
prev, r, g, b = None, 0, 0, 0
def id_to_random_color(number):
global prev, r, g, b
if number != prev:
r = random.random()
g = random.random()
b = random.random()
prev = number
return r, g, b, 1.0
Run Code Online (Sandbox Code Playgroud)
更新:
正如 AndrewMcDowell 在他的评论中所述,如果在不连续的情况下重复输入,该函数可能会返回不同的值。
这是一个可能的解决方法:
import random
memory = {}
def id_to_random_color(number, memory):
if not number in memory:
r = random.random()
g = random.random()
b = random.random()
memory[number] = (r, g, b, 1.0)
return memory[number]
Run Code Online (Sandbox Code Playgroud)
进一步更新:
相同的函数骨架甚至可以用于计算哈希:
memory = {}
def id_to_random_color(number):
if not number in memory:
numByte = str.encode(number)
hashObj = hashlib.sha1(numByte).digest()
r, g, b = hashObj[-1] / 255.0, hashObj[-2] / 255.0, hashObj[-3] / 255.0
memory[number]= (r, g, b, 1.0)
return r, g, b, 1.0
else:
return memory[number]
Run Code Online (Sandbox Code Playgroud)
尽管语法有点冗长,但该else语句提高了一点性能,避免了后续的内存写入和读取(正如杰克在他的回答中所述)。