python,随机播放直到列表完全不同
python, shuffle until lists are completely different
我想问一下如何洗牌,也许是在一个 while 循环中,直到所有列表都完全不同(就像在数独中一样)?
#lists you want to shuffle
s1 = [1, 2, 3, 4]
s2 = [1, 2, 3, 4]
s3 = [1, 2, 3, 3]
s4 = [1, 2, 3, 4]
def mid_generator():
while True:
random.shuffle(s1)
random.shuffle(s2)
random.shuffle(s3)
random.shuffle(s4)
# if ... all lists are different...:
#break
return s1, s2, s3, s4
使得第i行第j列的次数只有一次:
s1 = [3, 1, 2, 4]
s2 = [4, 2, 1, 3]
s3 = [2, 4, 3, 1]
s4 = [1, 3, 4, 2]
如果我尝试使用 if s1[0] != s2[0] 的长 if 语句....输出是错误的。
也许你能帮我。
这仍然是一个低效的算法,因为它是基于你的原始代码,但你可以将每个位置的元素放入集合中并检查它们的长度; len({1, 2, 3, 3})
将是 3
,因为只有 3 个唯一元素:
import random
#lists you want to shuffle
s1 = [1, 2, 3, 4]
s2 = [1, 2, 3, 4]
s3 = [1, 2, 3, 4]
s4 = [1, 2, 3, 4]
def mid_generator():
while True:
random.shuffle(s1)
random.shuffle(s2)
random.shuffle(s3)
random.shuffle(s4)
test0 = {s1[0], s2[0], s3[0], s4[0]}
test1 = {s1[1], s2[1], s3[1], s4[1]}
test2 = {s1[2], s2[2], s3[2], s4[2]}
test3 = {s1[3], s2[3], s3[3], s4[3]}
if len(test0) == len(test1) == len(test2) == len(test3) == 4:
break
return s1, s2, s3, s4
示例交互输出:
>>> mid_generator()
([3, 4, 2, 1], [1, 2, 4, 3], [4, 3, 1, 2], [2, 1, 3, 4])
这会起作用 - 但它不是最优的 - 但是 if 检查会起作用
def mid_generator():
while True:
random.shuffle(s1)
random.shuffle(s2)
random.shuffle(s3)
random.shuffle(s4)
if not (s1 == s2 or s1 == s3 or s1 == s4 or s2 == s3 or s2 == s4 or s3 == s4):
break
return s1, s2, s3, s4
它非常难看,但如果您小心地正确比较每个列表中的每一列,那么 and
语句的长列表也可以正常工作:
def mid_generator():
while True:
random.shuffle(s1)
random.shuffle(s2)
random.shuffle(s3)
random.shuffle(s4)
if ( s1[0] != s2[0] and s1[0] != s3[0] and s1[0] != s4[0]
and s2[0] != s3[0] and s2[0] != s4[0] and s3[0] != s4[0]
and s1[1] != s2[1] and s1[1] != s3[1] and s1[1] != s4[1]
and s2[1] != s3[1] and s2[1] != s4[1] and s3[1] != s4[1]
and s1[2] != s2[2] and s1[2] != s3[2] and s1[2] != s4[2]
and s2[2] != s3[2] and s2[2] != s4[2] and s3[2] != s4[2]
and s1[3] != s2[3] and s1[3] != s3[3] and s1[3] != s4[3]
and s2[3] != s3[3] and s2[3] != s4[3] and s3[3] != s4[3]):
break
return s1, s2, s3, s4
为了完整起见,这里有一个任意列表长度的通用版本:
def mid_generator(n):
s = [list(range(1, n+1)) for x in range(n)]
while True:
for x in s:
random.shuffle(x)
for i in range(n):
test = {s[j][i] for j in range(n)}
if len(test) != n:
break
else:
return s
return None # never hit
互动:
>>> mid_generator(1)
[[1]]
>>> mid_generator(2)
[[1, 2], [2, 1]]
>>> mid_generator(3)
[[1, 3, 2], [3, 2, 1], [2, 1, 3]]
>>> mid_generator(4)
[[2, 4, 1, 3], [4, 2, 3, 1], [1, 3, 2, 4], [3, 1, 4, 2]]
>>> mid_generator(5)
[[4, 5, 2, 1, 3], [1, 2, 3, 5, 4], [3, 4, 5, 2, 1], [5, 1, 4, 3, 2], [2, 3, 1, 4, 5]]
>>> mid_generator(6)
(还在等...)
正在使用Fisher-Yates shuffle based on code from geegksforgeeks。修改以下代码以确保该值永远不会放在原始索引处。
def fisher_yates_shuffle_diff(orig_list):
result_list = orig_list.copy()
list_len = len(orig_list)
indc_list = list(range(0, list_len))
for i in range(list_len-1, 0, -1):
# Pick a random index from 0 to i
indc = indc_list.copy()
# Remove current index
indc.remove(i)
j = indc[random.randint(0, i)]
# Swap arr[i] with the element at random index
result_list[i], result_list[j] = result_list[j], result_list[i]
return result_list
我想问一下如何洗牌,也许是在一个 while 循环中,直到所有列表都完全不同(就像在数独中一样)?
#lists you want to shuffle
s1 = [1, 2, 3, 4]
s2 = [1, 2, 3, 4]
s3 = [1, 2, 3, 3]
s4 = [1, 2, 3, 4]
def mid_generator():
while True:
random.shuffle(s1)
random.shuffle(s2)
random.shuffle(s3)
random.shuffle(s4)
# if ... all lists are different...:
#break
return s1, s2, s3, s4
使得第i行第j列的次数只有一次:
s1 = [3, 1, 2, 4]
s2 = [4, 2, 1, 3]
s3 = [2, 4, 3, 1]
s4 = [1, 3, 4, 2]
如果我尝试使用 if s1[0] != s2[0] 的长 if 语句....输出是错误的。 也许你能帮我。
这仍然是一个低效的算法,因为它是基于你的原始代码,但你可以将每个位置的元素放入集合中并检查它们的长度; len({1, 2, 3, 3})
将是 3
,因为只有 3 个唯一元素:
import random
#lists you want to shuffle
s1 = [1, 2, 3, 4]
s2 = [1, 2, 3, 4]
s3 = [1, 2, 3, 4]
s4 = [1, 2, 3, 4]
def mid_generator():
while True:
random.shuffle(s1)
random.shuffle(s2)
random.shuffle(s3)
random.shuffle(s4)
test0 = {s1[0], s2[0], s3[0], s4[0]}
test1 = {s1[1], s2[1], s3[1], s4[1]}
test2 = {s1[2], s2[2], s3[2], s4[2]}
test3 = {s1[3], s2[3], s3[3], s4[3]}
if len(test0) == len(test1) == len(test2) == len(test3) == 4:
break
return s1, s2, s3, s4
示例交互输出:
>>> mid_generator()
([3, 4, 2, 1], [1, 2, 4, 3], [4, 3, 1, 2], [2, 1, 3, 4])
这会起作用 - 但它不是最优的 - 但是 if 检查会起作用
def mid_generator():
while True:
random.shuffle(s1)
random.shuffle(s2)
random.shuffle(s3)
random.shuffle(s4)
if not (s1 == s2 or s1 == s3 or s1 == s4 or s2 == s3 or s2 == s4 or s3 == s4):
break
return s1, s2, s3, s4
它非常难看,但如果您小心地正确比较每个列表中的每一列,那么 and
语句的长列表也可以正常工作:
def mid_generator():
while True:
random.shuffle(s1)
random.shuffle(s2)
random.shuffle(s3)
random.shuffle(s4)
if ( s1[0] != s2[0] and s1[0] != s3[0] and s1[0] != s4[0]
and s2[0] != s3[0] and s2[0] != s4[0] and s3[0] != s4[0]
and s1[1] != s2[1] and s1[1] != s3[1] and s1[1] != s4[1]
and s2[1] != s3[1] and s2[1] != s4[1] and s3[1] != s4[1]
and s1[2] != s2[2] and s1[2] != s3[2] and s1[2] != s4[2]
and s2[2] != s3[2] and s2[2] != s4[2] and s3[2] != s4[2]
and s1[3] != s2[3] and s1[3] != s3[3] and s1[3] != s4[3]
and s2[3] != s3[3] and s2[3] != s4[3] and s3[3] != s4[3]):
break
return s1, s2, s3, s4
为了完整起见,这里有一个任意列表长度的通用版本:
def mid_generator(n):
s = [list(range(1, n+1)) for x in range(n)]
while True:
for x in s:
random.shuffle(x)
for i in range(n):
test = {s[j][i] for j in range(n)}
if len(test) != n:
break
else:
return s
return None # never hit
互动:
>>> mid_generator(1)
[[1]]
>>> mid_generator(2)
[[1, 2], [2, 1]]
>>> mid_generator(3)
[[1, 3, 2], [3, 2, 1], [2, 1, 3]]
>>> mid_generator(4)
[[2, 4, 1, 3], [4, 2, 3, 1], [1, 3, 2, 4], [3, 1, 4, 2]]
>>> mid_generator(5)
[[4, 5, 2, 1, 3], [1, 2, 3, 5, 4], [3, 4, 5, 2, 1], [5, 1, 4, 3, 2], [2, 3, 1, 4, 5]]
>>> mid_generator(6)
(还在等...)
正在使用Fisher-Yates shuffle based on code from geegksforgeeks。修改以下代码以确保该值永远不会放在原始索引处。
def fisher_yates_shuffle_diff(orig_list):
result_list = orig_list.copy()
list_len = len(orig_list)
indc_list = list(range(0, list_len))
for i in range(list_len-1, 0, -1):
# Pick a random index from 0 to i
indc = indc_list.copy()
# Remove current index
indc.remove(i)
j = indc[random.randint(0, i)]
# Swap arr[i] with the element at random index
result_list[i], result_list[j] = result_list[j], result_list[i]
return result_list