【问题标题】:Why does random.shuffle return None?为什么 random.shuffle 返回 None?
【发布时间】:2013-07-13 01:26:10
【问题描述】:

为什么random.shuffle 在 Python 中返回 None?

>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None

如何获得洗牌后的值而不是None?

【问题讨论】:

标签: python list random shuffle


【解决方案1】:

random.shuffle() 更改x 列表就地。

就地改变结构的 Python API 方法通常返回 None,而不是修改后的数据结构。

>>> x = ['foo', 'bar', 'black', 'sheep']
>>> random.shuffle(x)
>>> x
['black', 'bar', 'sheep', 'foo']

如果您想基于现有列表创建一个 新 随机打乱列表,其中现有列表保持有序,您可以使用 random.sample() 和输入的完整长度:

random.sample(x, len(x))     

您还可以使用sorted() 和random.random() 作为排序键:

shuffled = sorted(x, key=lambda k: random.random())

但这会调用排序(O(N log N) 操作),而对输入长度的采样仅需要 O(N) 操作(使用与 random.shuffle() 相同的过程,从收缩池中交换随机值)。

演示:

>>> import random
>>> x = ['foo', 'bar', 'black', 'sheep']
>>> random.sample(x, len(x))
['bar', 'sheep', 'black', 'foo']
>>> sorted(x, key=lambda k: random.random())
['sheep', 'foo', 'black', 'bar']
>>> x
['foo', 'bar', 'black', 'sheep']

【讨论】:

  • 真正保证使用随机值key 函数吗?如果比较不一致,一些快速排序算法就会失败。我可以看到这两种方式都有效,具体取决于实现(decorate-sort-undecorate 只需要在每个元素上应用一次key,因此将被明确定义)。
  • @torek:Python 在使用 key 可调用对象进行排序时使用 decorate-sort-undecorate。所以是的,这是有保证的,因为每个值都被赋予了一次随机密钥。
  • @MartijnPieters 我猜你在调用random.sample时颠倒了论点
【解决方案2】:

为什么,真的?

1。效率

shuffle 修改列表。 这很好,因为如果您不再需要原始列表,复制一个大列表将是纯粹的开销。

2。 Pythonic 风格

根据pythonic style 的“显式优于隐式” 原则,返回列表将是一个坏主意,因为这样可能会认为它是新的,虽然实际上不是。

但我不喜欢这样!

如果你确实需要一个新的列表,你将不得不写类似

new_x = list(x)  # make a copy
random.shuffle(new_x)

这是非常明确的。 如果您经常需要这个习语,请将其包装在一个返回 new_x 的函数 shuffled(参见 sorted)中。

【讨论】:

    【解决方案3】:

    这个方法也行。

    import random
    shuffled = random.sample(original, len(original))
    

    【讨论】:

      【解决方案4】:

      在适当位置改变结构的 Python API 返回 None 作为输出。

      list = [1,2,3,4,5,6,7,8]
      print(list)
      

      输出:[1、2、3、4、5、6、7、8]

      from random import shuffle
      print(shuffle(list))
      

      输出:无

      from random import sample
      print(sample(list, len(list)))
      

      输出:[7, 3, 2, 4, 5, 6, 1, 8]

      【讨论】:

        【解决方案5】:

        您可以按照其他人的说明使用random.sample() 返回随机列表。它通过从列表中不替换采样 k 个元素来工作。 因此,如果您的列表中有重复的元素,它们将被唯一处理。

        >>> l = [1,4,5,3,5]
        >>> random.sample(l,len(l))
        [4, 5, 5, 3, 1]
        >>> random.sample(l,len(l)-1)
        [4, 1, 5, 3]
        >>> random.sample(l,len(l)-1)
        [3, 5, 5, 1]
        

        【讨论】:

          【解决方案6】:

          这样的概念让我大吃一惊:

          from random import shuffle
          x = ['foo','black','sheep'] #original list
          y = list(x) # an independent copy of the original
          for i in range(5):
              print shuffle(y) # shuffles the original "in place" prints "None" return
              print x,y #prints original, and shuffled independent copy
          
          >>>
          None
          ['foo', 'black', 'sheep'] ['foo', 'black', 'sheep']
          None
          ['foo', 'black', 'sheep'] ['black', 'foo', 'sheep']
          None
          ['foo', 'black', 'sheep'] ['sheep', 'black', 'foo']
          None
          ['foo', 'black', 'sheep'] ['black', 'foo', 'sheep']
          None
          ['foo', 'black', 'sheep'] ['sheep', 'black', 'foo']
          

          【讨论】:

          【解决方案7】:

          根据docs:

          将序列 x 打乱。可选参数 random 是 0 参数函数返回 [0.0, 1.0) 中的随机浮点数;经过 默认,这是函数 random()。

          >>> x = ['foo','bar','black','sheep']
          >>> from random import shuffle
          >>> shuffle(x)
          >>> x
          ['bar', 'black', 'sheep', 'foo']
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-11-29
            • 2015-06-18
            • 2016-06-20
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多