【问题标题】:Python random listPython随机列表
【发布时间】:2016-03-01 20:40:50
【问题描述】:

我是 Python 新手,在创建随机列表时遇到了一些问题。

我正在使用random.sample(range(x, x), y)

我想得到 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

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

【问题讨论】:

  • 是的,但只有数字 1-4 :)
  • 你想生成一个随机的拉丁方吗?
  • @John Coleman,是的,我需要生成一个拉丁方格

标签: python list random


【解决方案1】:

我将构建一个随机拉丁方格 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)

【讨论】:

    【解决方案2】:

    可能最简单的方法是创建一个有效矩阵,然后打乱行,然后打乱列:

    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]]
    

    这应该能够以相等的概率创建任何有效的矩阵。在做了一些阅读之后,这似乎仍然存在偏差,尽管我还没有完全理解为什么。

    【讨论】:

      【解决方案3】:

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

      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)
      

      【讨论】:

        【解决方案4】:

        那么完全随机:

        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)
        

        【讨论】:

        • 这可能是最好的答案。简短而有效。在这里,我正在做过于复杂的功能来做到这一点。不错 +1
        • 这实际上与我的答案相同,只是编码不同。
        【解决方案5】:

        由于没有明确的数学理论,我不信任任何东西,除了有点碰运气的方法。特别是,回溯方法可能会引入微妙的偏差:

        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]
        

        【讨论】:

        • 非常感谢你们,我要试验一下:D
        • 这种方法完全没有偏差,但是随着 N 的增长,这是一种非常效率低下的方法。最后一行有 N!排列,但只有 1 是可行的。这使运行时间至少为 O(N!)。根据 Python 随机数生成器内部的位数,它可能永远不会因大 N 而终止。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-09
        • 1970-01-01
        • 2012-02-21
        • 2021-05-24
        • 2019-04-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多