在 Python 查询中生成随机列表
Generating random lists in Python query
我希望我的程序获取从 1 到 X 的数字,并在 X/2 个列表之间随机分配这些数字 Y 次。我不想在一次洗牌中重复一个数字,我也不希望列表重复。因此,如果有列表 [1,2],则在同一洗牌中不应该有另一个包含 1 或 2 的列表,并且整个结果中不应该有另一个 [1,2] 或 [2,1]。
这是我想到的,但是,它一直在重复数字。有什么建议吗?
import random
def Shuffler():
amount = int(raw_input("Numbers up to: "))
times = int(raw_input("Number of shuffles: "))
numberslist = range(1,amount+1)
twos = []
thisshuffle = []
final = []
while len(final) < (amount/2)*times:
twos = []
thisshuffle = []
while len(twos) < 2:
if len(numberslist)!=0:
randomnumber = random.choice(numberslist)
if (randomnumber in twos) or (randomnumber in thisshuffle):
numberslist.remove(randomnumber)
else:
twos.append(randomnumber)
thisshuffle.append(randomnumber)
numberslist.remove(randomnumber)
else:
numberslist = range(1,amount+1)
if (twos or list(reversed(twos))) not in final:
final.append(twos)
k=0
for i in range(times): #this shit prints shit
print "%s:" % (i+1), final[k:k+amount/2]
print
k = k + amount/2
Shuffler()
Shuffler()
您不希望在一次随机播放中有任何重复的数字,以及任何重复的列表...等等。这不是一件容易的事。另外一个事实是,唯一的数字集是固定的,不能设置得太高。例如,如果您设置 "Numbers up to:" 5,并且 "Number of shuffles: " 20,您肯定会得到重复的数字。
我知道你的代码的问题是在这个 if 语句中:
if (twos or list(reversed(twos))) not in final:
final.append(twos)
(twos or list(reversed(twos))) 逻辑或,结果为twos,因为twos不为空。我建议您将 if 语句更改为:
if (twos not in final) and (list(reversed(twos)) not in final):
final.append(twos)
以下代码 (python 2.7x) 使用排列和洗牌生成数字列表。接下来,使列表唯一(例如,同一列表中没有 [1,2] 和 [2,1])。然后,根据用户指定的洗牌次数将它们分组。按任意字母,脚本将退出。希望对您有所帮助:
from itertools import permutations
from random import shuffle
def Shuffler():
try:
amount = input("Numbers up to: ")
p = list(permutations(range(1, amount + 1), 2))
p_uniq = [list(x) for x in p if x[::-1] in p and x[0]<=x[1]]
shuf_max = len(p_uniq) /(amount / 2)
times = shuf_max + 1 # set a higher value to trigger prompt
while times > shuf_max:
shuffle(p_uniq) # shuffle the unique list in place
times = input("Number of shuffles (MAX %s): " % (shuf_max))
else:
for i, group in enumerate(list(zip(*[iter(p_uniq[: (amount /2) * times + 1])]* (amount/2)))):
print "%i: " % (i + 1), list(group)
Shuffler()
except:
print 'quitting...'
Shuffler()
输出:
Numbers up to: 10
Number of shuffles (MAX 9): 8
1: [[6, 7], [1, 9], [2, 5], [5, 9], [9, 10]]
2: [[1, 10], [3, 8], [4, 10], [8, 10], [1, 5]]
3: [[1, 4], [6, 8], [3, 6], [2, 4], [4, 7]]
4: [[2, 10], [5, 8], [3, 9], [1, 7], [4, 9]]
5: [[1, 2], [7, 9], [1, 3], [6, 9], [1, 6]]
6: [[2, 9], [4, 8], [3, 5], [8, 9], [7, 10]]
7: [[2, 7], [2, 3], [7, 8], [3, 7], [3, 10]]
8: [[3, 4], [2, 6], [5, 6], [5, 7], [4, 6]]
Numbers up to:
正如 ccf 所指出的,您的要求并非微不足道。再执行几个步骤,您就会拥有一个数独生成器:)
我尝试了一些解决方案,但它们要么没有产生随机输出,要么效率很低。 Ccf 的解决方案写得很好,但似乎有同样的问题;它产生有序的输出(例如 [1, 2], [1, 3], [1, 4], [1, 5], [1, 6]
)。
@cff - 使用 itertools.combinations 而不是 itertools.permutations 来避免产生重复不是更好吗?
这是一个与 ccf 非常相似的 "solution"(也不产生随机输出):
import itertools
def Shuffler():
amount = int(raw_input("Numbers up to: "))
times = int(raw_input("Number of shuffles: "))
rng = range(1, amount+1)
perms = list(itertools.combinations(rng, 2))
lst_single = []
lst_all = []
for p in perms:
if len(lst_all) >= times:
for i, lst in enumerate(lst_all):
print str(i+1) + ": ", lst
break
if len(lst_single) == amount/2:
lst_all.append(lst_single)
lst_single = []
elif p[0] < p[1]:
p = list(p)
lst_single.append(p)
Shuffler()
输出
Numbers up to: 6
Number of shuffles: 3
1: [[1, 2], [1, 3], [1, 4]]
2: [[1, 6], [2, 3], [2, 4]]
3: [[2, 6], [3, 4], [3, 5]]
这里有一个有点老套的解决方案,它似乎可以产生您想要的输出,但效率低下。它依赖于一个集合来过滤掉不需要的组合,但仍然浪费资源来首先产生它们。
import random
def Shuffler():
amount = int(raw_input("Numbers up to: "))
times = int(raw_input("Number of shuffles: "))
rng = range(1, amount+1)
final = []
lst_len = amount/2
combos_unique = set()
while len(combos_unique) < lst_len*times:
combo_rand = random.sample(rng, 2)
if combo_rand[0] < combo_rand[1]:
combos_unique.add(tuple(combo_rand))
tmp = []
for combo in combos_unique:
tmp.append(list(combo))
if len(tmp) >= lst_len:
final.append(tmp)
tmp = []
for i, lst in enumerate(final):
print str(i+1) + ": ", lst
Shuffler()
输出
Numbers up to: 6
Number of shuffles: 3
1: [[2, 6], [4, 6], [5, 6]]
2: [[4, 5], [1, 3], [1, 6]]
3: [[3, 4], [2, 4], [3, 5]]
我希望我的程序获取从 1 到 X 的数字,并在 X/2 个列表之间随机分配这些数字 Y 次。我不想在一次洗牌中重复一个数字,我也不希望列表重复。因此,如果有列表 [1,2],则在同一洗牌中不应该有另一个包含 1 或 2 的列表,并且整个结果中不应该有另一个 [1,2] 或 [2,1]。
这是我想到的,但是,它一直在重复数字。有什么建议吗?
import random
def Shuffler():
amount = int(raw_input("Numbers up to: "))
times = int(raw_input("Number of shuffles: "))
numberslist = range(1,amount+1)
twos = []
thisshuffle = []
final = []
while len(final) < (amount/2)*times:
twos = []
thisshuffle = []
while len(twos) < 2:
if len(numberslist)!=0:
randomnumber = random.choice(numberslist)
if (randomnumber in twos) or (randomnumber in thisshuffle):
numberslist.remove(randomnumber)
else:
twos.append(randomnumber)
thisshuffle.append(randomnumber)
numberslist.remove(randomnumber)
else:
numberslist = range(1,amount+1)
if (twos or list(reversed(twos))) not in final:
final.append(twos)
k=0
for i in range(times): #this shit prints shit
print "%s:" % (i+1), final[k:k+amount/2]
print
k = k + amount/2
Shuffler()
Shuffler()
您不希望在一次随机播放中有任何重复的数字,以及任何重复的列表...等等。这不是一件容易的事。另外一个事实是,唯一的数字集是固定的,不能设置得太高。例如,如果您设置 "Numbers up to:" 5,并且 "Number of shuffles: " 20,您肯定会得到重复的数字。
我知道你的代码的问题是在这个 if 语句中:
if (twos or list(reversed(twos))) not in final:
final.append(twos)
(twos or list(reversed(twos))) 逻辑或,结果为twos,因为twos不为空。我建议您将 if 语句更改为:
if (twos not in final) and (list(reversed(twos)) not in final):
final.append(twos)
以下代码 (python 2.7x) 使用排列和洗牌生成数字列表。接下来,使列表唯一(例如,同一列表中没有 [1,2] 和 [2,1])。然后,根据用户指定的洗牌次数将它们分组。按任意字母,脚本将退出。希望对您有所帮助:
from itertools import permutations
from random import shuffle
def Shuffler():
try:
amount = input("Numbers up to: ")
p = list(permutations(range(1, amount + 1), 2))
p_uniq = [list(x) for x in p if x[::-1] in p and x[0]<=x[1]]
shuf_max = len(p_uniq) /(amount / 2)
times = shuf_max + 1 # set a higher value to trigger prompt
while times > shuf_max:
shuffle(p_uniq) # shuffle the unique list in place
times = input("Number of shuffles (MAX %s): " % (shuf_max))
else:
for i, group in enumerate(list(zip(*[iter(p_uniq[: (amount /2) * times + 1])]* (amount/2)))):
print "%i: " % (i + 1), list(group)
Shuffler()
except:
print 'quitting...'
Shuffler()
输出:
Numbers up to: 10
Number of shuffles (MAX 9): 8
1: [[6, 7], [1, 9], [2, 5], [5, 9], [9, 10]]
2: [[1, 10], [3, 8], [4, 10], [8, 10], [1, 5]]
3: [[1, 4], [6, 8], [3, 6], [2, 4], [4, 7]]
4: [[2, 10], [5, 8], [3, 9], [1, 7], [4, 9]]
5: [[1, 2], [7, 9], [1, 3], [6, 9], [1, 6]]
6: [[2, 9], [4, 8], [3, 5], [8, 9], [7, 10]]
7: [[2, 7], [2, 3], [7, 8], [3, 7], [3, 10]]
8: [[3, 4], [2, 6], [5, 6], [5, 7], [4, 6]]
Numbers up to:
正如 ccf 所指出的,您的要求并非微不足道。再执行几个步骤,您就会拥有一个数独生成器:)
我尝试了一些解决方案,但它们要么没有产生随机输出,要么效率很低。 Ccf 的解决方案写得很好,但似乎有同样的问题;它产生有序的输出(例如 [1, 2], [1, 3], [1, 4], [1, 5], [1, 6]
)。
@cff - 使用 itertools.combinations 而不是 itertools.permutations 来避免产生重复不是更好吗?
这是一个与 ccf 非常相似的 "solution"(也不产生随机输出):
import itertools
def Shuffler():
amount = int(raw_input("Numbers up to: "))
times = int(raw_input("Number of shuffles: "))
rng = range(1, amount+1)
perms = list(itertools.combinations(rng, 2))
lst_single = []
lst_all = []
for p in perms:
if len(lst_all) >= times:
for i, lst in enumerate(lst_all):
print str(i+1) + ": ", lst
break
if len(lst_single) == amount/2:
lst_all.append(lst_single)
lst_single = []
elif p[0] < p[1]:
p = list(p)
lst_single.append(p)
Shuffler()
输出
Numbers up to: 6
Number of shuffles: 3
1: [[1, 2], [1, 3], [1, 4]]
2: [[1, 6], [2, 3], [2, 4]]
3: [[2, 6], [3, 4], [3, 5]]
这里有一个有点老套的解决方案,它似乎可以产生您想要的输出,但效率低下。它依赖于一个集合来过滤掉不需要的组合,但仍然浪费资源来首先产生它们。
import random
def Shuffler():
amount = int(raw_input("Numbers up to: "))
times = int(raw_input("Number of shuffles: "))
rng = range(1, amount+1)
final = []
lst_len = amount/2
combos_unique = set()
while len(combos_unique) < lst_len*times:
combo_rand = random.sample(rng, 2)
if combo_rand[0] < combo_rand[1]:
combos_unique.add(tuple(combo_rand))
tmp = []
for combo in combos_unique:
tmp.append(list(combo))
if len(tmp) >= lst_len:
final.append(tmp)
tmp = []
for i, lst in enumerate(final):
print str(i+1) + ": ", lst
Shuffler()
输出
Numbers up to: 6
Number of shuffles: 3
1: [[2, 6], [4, 6], [5, 6]]
2: [[4, 5], [1, 3], [1, 6]]
3: [[3, 4], [2, 4], [3, 5]]