提问人:JayDee 提问时间:8/7/2023 更新时间:8/8/2023 访问量:37
将列表索引与其他列表进行核对,并在它们匹配时进行随机排序
Checking list indexes against other lists and shuffling when they match
问:
我有多个项目列表,我需要对其进行洗牌以确保:
- 一个列表中给定索引处的项目与另一个列表中的项不在同一位置
- 列表的最后一项与下一项列表的第一项不同
我已经编写了下面的代码来迭代和进行检查,但它永远运行,然后超时。列表很长,所以它们具有匹配值的可能性很低,我只需要确保它不会发生。我认为循环中一定存在错误,我只是无法发现它。
shuffled_list = True
while shuffled_list:
shuffled_list = False
for i in range(len(list1)):
if (
list1[i] == list2[i] or
list1[i] == list3[i] or
list1[i] == list4[i] or
list2[i] == list3[i] or
list2[i] == list4[i] or
list3[i] == list4[i]
):
random.shuffle(list1)
random.shuffle(list2)
random.shuffle(list3)
random.shuffle(list4)
shuffled_list = True
break
if list1[i][-1] == list2[i][0]:
random.shuffle(list1)
random.shuffle(list2)
shuffled_list = True
break
if list2[i][-1] == list3[i][0]:
random.shuffle(list2)
random.shuffle(list3)
shuffled_list = True
break
if list3[i][-1] == list4[i][0]:
random.shuffle(list3)
random.shuffle(list4)
shuffled_list = True
break
if not shuffled_list:
break
答:
0赞
Alain T.
8/8/2023
#1
当你遇到冲突时,重新洗牌一切势必会产生更多的冲突。更好的策略是逐步洗牌每个列表,确保它不会与前面的列表发生冲突。累积起来,所有列表都将符合您的条件。
list1 = [1,2,3,4,5,6]
list2 = [3,4,5,6,7,8]
list3 = [7,8,9,0,1,2]
list4 = [2,4,6,8,0,3]
lists = [list1,list2,list3,list4] # list of lists
for i,lst in enumerate(lists):
while True: # shuffle lst until no conflict
random.shuffle(lst)
if any(n in col for *col,n in zip(*lists[:i+1])):
continue # column conflict
if i and lst[0]==lists[i-1][-1]:
continue # last/first conflict
break # no conflict
输出:
print(*lists,sep="\n")
[1, 3, 6, 4, 5, 2]
[6, 4, 7, 5, 8, 3]
[9, 1, 0, 7, 2, 8]
[0, 8, 2, 3, 4, 6]
检查列间冲突的条件用于获取元组,其中每列中的数字直至当前列表。它将其分为(先前列表中的列值)和当前列表中的值。如果存在于先前列表的同一列中,则存在冲突,并且洗牌循环将继续迭代。zip(*lists[:i+1])
col
n
n
要检查第二个条件,请将当前列表 () 的第一项与前一个列表 () 的最后一项进行比较。lst[0]
lists[i-1][-1]
请注意,由于您说过冲突的可能性很低,因此这种方法不应陷入死胡同,即列表没有可能的洗牌顺序。如果存在这种可能性,则需要某种形式的回溯来重新启动或重新打乱以前的列表(最坏的情况是动态规划求解器)
这是相同的算法,但在同一列表上尝试 x 次后洗牌不起作用时具有重置机制(尝试次数是列表的长度,但您可以选择任何您想要的数字):
lists = [list1,list2,list3,list4] # list of lists
i = 0
while i<len(lists):
lst = lists[i]
for _ in lst: # shuffle lst until no conflict or x times
random.shuffle(lst)
if any(n in col for *col,n in zip(*lists[:i+1])):
continue # column conflict
if i and lst[0]==lists[i-1][-1]:
continue # last/first conflict
i += 1
break # no conflict (next list)
else: i = 0 # still conflicts, restart
评论
list1[i][-1] == list2[i][0]
list1[i]
list2[i]
[i]