Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何随机化列表以满足条件_Python_List_Random - Fatal编程技术网

Python 如何随机化列表以满足条件

Python 如何随机化列表以满足条件,python,list,random,Python,List,Random,我想生成一个列表的n个随机版本,这样每次随机化的顺序都不同于之前的顺序,而且每个元素的位置也必须不同于之前的列表。我已经生成了一个列表,列出了列表中所有可能的排列方式,但我一直在思考如何选择符合我条件的子列表。我在想也许一个列表理解可以工作,但不知道如何完成它 # constraints: n <= 12 lst = ['John', 'William', 'Michael', 'Victor', 'Tom', 'Charley', 'Patrick', 'David'] permut

我想生成一个列表的n个随机版本,这样每次随机化的顺序都不同于之前的顺序,而且每个元素的位置也必须不同于之前的列表。我已经生成了一个列表,列出了列表中所有可能的排列方式,但我一直在思考如何选择符合我条件的子列表。我在想也许一个列表理解可以工作,但不知道如何完成它

# constraints: n <= 12

lst = ['John', 'William', 'Michael', 'Victor', 'Tom', 'Charley', 'Patrick', 'David']

permutations = list(itertools.permutations(lst))

randomized_lists = [i for i in permutations if <conditions>]

#约束:n您可以使用以下列表:

result = [i for i in permutations if any(a != b for a, b in zip(i, lst))]

我们正在
any(a==b表示a,b在zip(i,lst)中)
测试
lst
中同一索引上是否有任何匹配项,并在这一行中进行排列。

这可以通过修改算法来完成,以避免将一项与自身交换。也就是说,对于k处的每个项(其中k从0开始),而不是在
[0,k]中选择一个随机项
[k,n-1]
(包括
k
),在
[0,k)
(k,n-1]
(不包括
k
)中选择一个随机项,并将k处的项与随机项交换


以下方法实现了这一想法:

import random

def shuffle_diff_pos(list):
  """ Returns a shuffled list in which 
      each item moves to a different position. """
  list=[x for x in list]
  if len(list)>=2:
    i=len(list)-1
    while i>0:
      k=random.randint(0, i-1)
      tmp=list[i];list[i]=list[k];list[k]=tmp
      i-=1
  return list

lst = ['John', 'William', 'Michael', 'Victor', 'Tom', 'Charley', 'Patrick', 'David']
randomized_lists = [shuffle_diff_pos(lst) for _ in range(12)]

只有第二个条件是必要的:如果所有元素都不在其原始位置,则顺序将不同。您可以根据规范生成一个列表,而不是查看所有可能的排列并随机选择一个(这比在满足您的条件之前洗牌更低效)

您的列表有8个元素,这意味着每个位置可以有7个选项中的一个(除了当前所在的元素之外)。这相当于将一个元素放在一个由零组成的矩阵中,这样就不会有任何一个元素与另一个元素占据同一行或列(正常无序排列),但由于元素不能位于主对角线上的限制,使事情变得复杂

你可以实现一个包含限制的洗牌。这将使你的列表随机化,而不必筛选大量的排列

使用索引以避免放置冲突可能比在交换每个元素时查找其位置更容易

n = len(lst)
ind = list(range(n))
for i in range(n - 1):
    # Case 1: Swap out necessary, conflictonly with self
    if ind[i] == i:
        swap_ind = random.randrange(i + 1, n)
    else:
        try:
            # Case 2: swap might cause conflict
            ind_of_i = ind.index(i, i + 1)
            swap_ind = random.randrange(i, n - 1)
            if swap_ind >= ind_of_i:
                swap_ind += 1
        except ValueError:
            # Case 3: no conflict, full range available
            swap_ind = random.randrange(i, n)
    ind[i], ind[swap_ind] = ind[swap_ind], ind[i]
现在,您有了一个无序索引列表,其中没有一个索引与开始索引的位置相同

result = [lst[i] for i in ind]
请记住,check
ind[swap\u ind]的实现
在时间上非常低效,并且有效地否定了排序索引而不是实际值的好处。您可以用第二个列表替换它,该列表维护索引的反向查找表,并将其与
ind
交换。结果将是
O(1)
查找和两倍的内存利用率


我不确定在所有可用排列的空间上,结果会有多一致,但我怀疑(a)对于您正在寻找的内容,它可能已经足够好了,以及(b)如果必要/可能,可以很容易地修改为更加统一。

你的条件是什么?@mario_sunny他们在问题中说。@mario_sunny每个元素在符合我条件的子列表中也必须有不同的位置。
-哪些条件?也许我不理解这个问题。@mario_sunny.OP想洗牌一个l以这样一种方式排列,即所有元素都不会在其原始位置结束。
any(zip(item,lst)中的a==b)
?你可以把
结果
做成一个生成器,这样你就不必一次构建整个过程。请随意编辑我的答案。我并不完全理解a和b的含义。
a和
b
都是大脑放屁。我的意思是
任何(a==b代表a,b在zip中(项目,lst))
。我不想碰你的代码。你根本不需要对
循环使用
。有了这个条件,你可以使用列表理解。我一直在研究一个内容和实现相同的答案。我认为结果不会100%一致,无法给出满意的解释或修复+1@Peter这似乎是一个很好的例子有趣的答案。你能给出一个示例代码吗?我不确定你的代码是否涵盖了交换元素的三种可能性。我发布了一个答案,基本上详细阐述了你最初的想法。我重新措辞了这个问题,并在这里得到了一个解决方案:@Clifton。改写后的代码在功能上与这个问题相同另一个问题建议随机洗牌并剔除不一致的元素。陷入这种方法的概率低得可以忽略,但仍然没有效率。你应该从这里选择一个答案。