在Python中使用限制重新排列列表

Fre*_*rik 6 python shuffle restrictions

我在使用Python(3)中的限制随机化列表时遇到问题.我已经看到了一些与此相关的其他问题,但它们似乎都没有解决我的问题.我是初学者,所以非常感谢任何帮助!

我正在设计一个使用两种刺激类型的实验:形状和颜色(每种刺激四种).我需要生成所有16种组合的排列,我用random.shuffle函数完成了这些排列:

import random

# letters are shapes, numbers are colors
x=["a1","a2","a3","a4","b1","b2","b3","b4","c1","c2","c3","c4","d1","d2","d3","d4"]

random.shuffle(x)
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.但是,我想避免在我的结果中连续出现两次形状(字母)或颜色(数字)(例如"a2"后跟"a4",或"c2"后跟"a2").

有没有办法做出这样的限制?
提前致谢!

sab*_*lel 5

处理这个问题的一种方法可能是有两个列表,一个是形状列表,一个是颜色列表。单独打乱每个列表。现在混合这两个列表。由于每个列表都是随机构建的,因此混合列表也是随机的,但您没有任何两个条目在一起。

请注意,使用 zip,您实际上会获得成对的集合,这将使您能够通过从结果中获取每对来处理测试。

在这种特殊情况下,每个形状都是形状列表的成员,而每种颜色都是颜色列表的成员

shapes = ['a', 'b', 'c', 'd']
colors = ['1', '2', '3', '4']
zip(shapes, colors)
[('a', '1'), ('b', '2'), ('c', '3'), ('d', '4')]
Run Code Online (Sandbox Code Playgroud)

这为我们提供了每个单独的洗牌,而不是一次生成所有 16 种可能性,然后对它们进行洗牌。这可能使您能够更好地生成测试。

如果您想确保两组列表在与前一组四组列表相同的位置上不具有相同的颜色或形状,那么您可以在根据之前的设置进行随机播放后进行测试。

testing = True
while testing:
    newcolors = colors
    random.shuffle(newcolors)
    # perform the test that you want to make get testresult True or False
    if testresult:
        colors = newcolors
        testing = False
Run Code Online (Sandbox Code Playgroud)

这将继续洗牌,直到 testresult 变为 True 并丢弃 random.shuffle() 中的所有无效结果


Dan*_*ini 2

像这样的事情应该在合理的时间内给出合理的答案

import random
while 1:
    choices = ["a1", "a2","a3","b1","b2","b3","c1","c2","c3"]

    shuffle = []

    last = ""

    while choices:
        l = choices
        if last:
            l = [x for x in l if x[0] != last[0] and x[1] != last[1]]
        if not l:
            #no valid solution
            break 
        newEl = random.choice(l)
        last = newEl
        shuffle.append(newEl)
        choices.remove(newEl)
    if not choices:
        print(shuffle)
        break
Run Code Online (Sandbox Code Playgroud)