2015-11-27 136 views
7

我是Python新手,在创建随机列表时遇到了一些问题。我正在使用random.sample(range(x, x), y)Python随机列表

我想4只列出具有独特的数字,从1-4,所以我一直在用这个

a = random.sample(range(1, 5), 4) 
b = random.sample(range(1, 5), 4) 
c = random.sample(range(1, 5), 4) 
d = random.sample(range(1, 5), 4) 

所以我得到例如

a = 1, 3, 2, 4 
b = 1, 4, 3, 2 
c = 2, 3, 1, 4 
d = 4, 2, 3, 1 

我怎样才能让这该列也是唯一的?

+0

是的,但只有数字1 - 4 :) – PythonUserNew

+0

你是否试图产生一个随机拉丁广场? –

+0

@ John Coleman,是的,我需要生成一个拉丁广场 – PythonUserNew

回答

1

也许最简单的方法是创建一个有效的矩阵,然后洗牌行,然后洗牌列:

import random 

def random_square(U): 
    U = list(U) 
    rows = [U[i:] + U[:i] for i in range(len(U))] 
    random.shuffle(rows) 
    rows_t = [list(i) for i in zip(*rows)] 
    random.shuffle(rows_t) 
    return rows_t 

用法:

>>> random_square(range(1, 1+4)) 
[[2, 3, 4, 1], [4, 1, 2, 3], [3, 4, 1, 2], [1, 2, 3, 4]] 

这应该能够创建具有相等概率的任何有效矩阵。 经过一番阅读后,似乎仍然存在偏见,尽管我还没有完全理解。

1

创建所有元素的列表,并填充行,删除使用过的元素。

import random 

def fill_line(length): 
    my_list = list(range(length)) 

    to_return = [] 

    for i in range(length): 
     x = random.choice(my_list) 

     to_return.append(x) 
     my_list.remove(x) 

    return to_return 

x = [fill_line(4) 
    for i in range(4)] 

print(x) 
3

如果没有一个清晰的数学理论,我不相信除了有点碰碰运气的方法之外的任何事情。特别地,回溯方法可以引入一个微妙偏压:

from random import shuffle 

def isLatin(square): 
    #assumes that square is an nxn list 
    #where each row is a permutation of 1..n 
    n = len(square[0]) 
    return all(len(set(col)) == n for col in zip(*square)) 

def randSquare(n): 
    row = [i for i in range(1,1+n)] 
    square = [] 
    for i in range(n): 
     shuffle(row) 
     square.append(row[:]) 
    return square 

def randLatin(n): 
    #uses a hit and miss approach 
    while True: 
     square = randSquare(n) 
     if isLatin(square): return square 

典型输出:

>>> s = randLatin(4) 
>>> for r in s: print(r) 

[4, 1, 3, 2] 
[2, 3, 4, 1] 
[1, 4, 2, 3] 
[3, 2, 1, 4] 
+0

非常感谢你们,我要试验并尝试一下:D – PythonUserNew

+0

这种方法完全没有偏见,但这是一种__very__效率低下的方法,但是作为N增长。最后一行有N!排列,但只有1个是可行的。这使运行时至少在O(N!)。根据Python随机数生成器在内部的位数,它可能永远不会终止于大N。 – orlp

2

完全随机的,则:

def gen_matrix(): 
    first_row = random.sample(range(1, 5), 4) 
    tmp = first_row + first_row 
    rows = [] 
    for i in range(4): 
     rows.append(tmp[i:i+4]) 
    return random.sample(rows, 4) 
+0

可能是最好的答案。简洁而有效。在这里,我做了过分复杂的功能。尼斯+1 –

+0

这与我的回答非常相似,只是编码不同。 – orlp

0

我将建立由1随机拉丁方)开始用一个随机排列,2)用循环填充行3)混洗行4)转置正方形5)再次混洗行:

from collections import deque 
from random import shuffle 

def random_latin_square(elements): 
    elements = list(elements) 
    shuffle(elements) 
    square = [] 
    for i in range(len(elements)): 
     square.append(list(elements)) 
     elements = elements[1:] + [elements[0]] 
    shuffle(square) 
    square[:] = zip(*square) 
    shuffle(square) 
    return square 

if __name__ == '__main__': 
    from pprint import pprint 
    square = random_latin_square('ABCD') 
    pprint(square)