以不同的索引顺序创建 5 个相同元素的 5 个列表

Creating 5 lists of the 5 same elements in different index order

提问人:Jb Melmi 提问时间:10/30/2023 最后编辑:wjandreaJb Melmi 更新时间:10/31/2023 访问量:127

问:

我正在为一个看似如此基本的问题而苦苦挣扎,但由于我仍然无法实施而让我发疯。

这是交易: 我有一个包含 5 个元素的列表,例如:

['A', 'B', 'C', 'D', 'E']

我想要列表中的元素,以便每个列表在不同的索引中包含相同的元素。例如,元素“A”在每个列表中将具有不同的索引位置。它应该是随机的,这样每次我运行代码时,我仍然有不同的列表。

喜欢这个:

['A', 'B', 'C', 'D', 'E']
['C', 'D', 'E', 'A', 'B']
['B', 'C', 'D', 'E', 'A']
['E', 'A', 'B', 'C', 'D']
['D', 'E', 'A', 'B', 'C']

我尝试使用迭代工具,我尝试将 if 语句放入 for 循环进入 for 循环,但显然它不起作用......我觉得解决方案非常简单,但我错过了一些东西。

python 列表 排列 随机算法

评论

4赞 Scott Hunter 10/30/2023
如果您显示您尝试过的代码,有人可能会帮助您修复它。
0赞 wizzwizz4 10/30/2023
您是否需要它们不同,或者这五个列表可以有重复的顺序?@ScottHunter我认为在这种情况下这无济于事。
0赞 wizzwizz4 10/30/2023
@juanpa.arrivillaga:进行编辑的理由是什么?
1赞 juanpa.arrivillaga 10/30/2023
@wizzwizz4始终对所有与 Python 相关的问题使用通用 [python] 标签。如果一个问题是针对某些 python 版本的,那么你可以添加一个特定于版本的标签,尽管现在,由于 Python 2 已经很好地通过了,它是 EOL 并且不再受支持,Python 是 Python 3。
4赞 Kelly Bundy 10/30/2023
您的示例看起来不是随机的,每一行只是第一行的旋转。这是故意的吗?

答:

-1赞 Ester Gjorek 10/30/2023 #1
import random

original_list = ['A', 'B', 'C', 'D', 'E']

# Number of lists you want to generate:
num_lists = 5

# Generate and print the shuffled lists:
for i in range(num_lists):
    shuffled_list = original_list.copy()
    random.shuffle(shuffled_list)
    print(shuffled_list)

您可以根据所需的列表数量更改代码。

评论

3赞 Matthias 10/30/2023
由于这是随机的,因此无法保证获得不同索引的元素。您甚至可以取回原始列表的顺序。
0赞 Jb Melmi 10/30/2023
@Matthias是的,你说得对,这就是我在这里关心的问题......
1赞 C.Nivs 10/30/2023 #2

为此,您可以使用:collections.deque

from collections import deque

d = deque('ABCDE')

for _ in range(len(d)):
    print(d)
    d.rotate()

deque(['A', 'B', 'C', 'D', 'E'])
deque(['E', 'A', 'B', 'C', 'D'])
deque(['D', 'E', 'A', 'B', 'C'])
deque(['C', 'D', 'E', 'A', 'B'])
deque(['B', 'C', 'D', 'E', 'A'])

要随机化,您需要对最终结果进行洗牌:

import random

lists = []

for _ in range(len(d)):
    lists.append(list(d))
    d.rotate()

random.shuffle(lists)

评论

1赞 user2390182 10/30/2023
这是显而易见的。但是,它不是随机的。
0赞 C.Nivs 10/30/2023
@user2390182否,但 OP 也不是示例。如果顺序应该是随机的,那么在事后重新洗牌旋转的顺序
0赞 user2390182 10/30/2023
如果它们都是彼此的旋转,则仍然不会是随机的。
1赞 C.Nivs 10/30/2023
@user2390182 “例如,元素'A'在每个列表中将具有不同的索引位置”。正确,因为所需的效果不是随机的
1赞 Kelly Bundy 10/30/2023
@user2390182 这至少在某种程度上是随机的。不清楚 OP 想要多少/什么随机性(到目前为止,他们忽略了我的问题......
1赞 tobias_k 10/30/2023 #3

不确定这是否是约束允许的随机性,但它至少比示例随机性强得多,同时保留所有约束:从示例中的“移位”列表开始,然后随机随机排列矩阵的行和列(或者,也许更简单,随机排列行,然后转置,然后再次随机排列行)。

import random

lst = ['A', 'B', 'C', 'D', 'E']
lsts = [lst[i:] + lst[:i] for i in range(5)]
random.shuffle(lsts)
lsts = list(map(list, zip(*lsts)))
random.shuffle(lsts)

之后,每一行和每一列都只包含一次每个元素,没有任何明显的模式。示例输出:

['C', 'A', 'D', 'E', 'B']
['B', 'E', 'C', 'D', 'A']
['E', 'C', 'A', 'B', 'D']
['A', 'D', 'B', 'C', 'E']
['D', 'B', 'E', 'A', 'C']

评论

0赞 tobias_k 10/30/2023
(我提出了这个想法,用于生成数独棋盘的“变体”,这些数独棋盘具有适当的唯一解决方案,而不是实现完整的数独生成算法;约束 - 每行和每列中的每个数字 - 与您的情况相同。
0赞 tobias_k 10/31/2023
出于某种原因,使用结果是相当非随机的(我最初使用它来获得可重复的结果),但是使用随机种子,结果确实看起来是随机的。random.seed(0)
1赞 Matthias 10/30/2023 #4

这有点棘手。您可以使用创建所有可能的排列,然后抛出那些与约束不匹配的排列。itertools.permutations

但是,由于你得到了所有的排列,所以你得到了像和这样的值。现在,第二个排列将始终被抛出。因此,您必须先洗牌所有排列。['B', 'A', 'D', 'E', 'C']['B', 'A', 'E', 'C', 'D']

import itertools
import random

def has_same_index(list_of_lists, list_to_compare):
    for inner_list in list_of_lists:
        for x, y in zip(inner_list, list_to_compare):
            if x == y:
                return True
    return False


data = ['A', 'B', 'C', 'D', 'E']

combis = list(itertools.permutations(data, 5))
random.shuffle(combis)

result = []
for combi in combis:
    if not has_same_index(result, combi):
        result.append(combi)
print(result)

这将为您提供如下结果

[('A', 'C', 'E', 'B', 'D'), ('D', 'E', 'C', 'A', 'B'), ('C', 'B', 'D', 'E', 'A'), ('E', 'A', 'B', 'D', 'C'), ('B', 'D', 'A', 'C', 'E')]

[('D', 'C', 'B', 'E', 'A'), ('B', 'A', 'C', 'D', 'E'), ('E', 'D', 'A', 'B', 'C'), ('C', 'B', 'E', 'A', 'D'), ('A', 'E', 'D', 'C', 'B')].

如果您需要将元组作为列表,则很容易转换它们。

评论

0赞 Jb Melmi 10/30/2023
感谢您提供此解决方案,这是我尝试过但从未实现的解决方案之一......我也会保留它!