【问题标题】:random.shuffle(range(10)) report TypeError [duplicate]random.shuffle(range(10)) 报告 TypeError [重复]
【发布时间】:2018-08-20 23:46:12
【问题描述】:

我想生成一个随机列表,

In [20]: num_arr = list(range(10))
In [22]: random.shuffle(num_arr)
In [23]: print(num_arr)
[8, 0, 7, 3, 9, 4, 1, 2, 6, 5]

不过,我试过了

In [24]: num_arr = range(10)
In [25]: random.shuffle(num_arr)
TypeError: 'range' object does not support item assignment

我打算了解为什么它不起作用背后的机制?
你能提供任何提示吗?

【问题讨论】:

  • 看起来随机播放功能使用像obj[0]这样的项目分配来就地移动项目。
  • 如果你使用random.sample(),你可以为所欲为。
  • 欢迎使用 python 3...shuffle(range()) 在 python 2.7 中工作正常 =)
  • 您使用的是 Python 3 吗?我在 Python 2.7 上试过了,没有问题。 Python 2.7 中的 range() 返回 list,但我知道 Python 3 将 range() 更改为与 Python 2 中的 xrange() 相同,因此可能存在差异。
  • @lenik: shuffle(range()) 是毫无意义的,如果你真的在调用中构造了新的rangerandom.sample(range(n), n) 至少会有用(因为它构造并返回一个全新的list)。

标签: python python-3.x


【解决方案1】:

random.shuffle 将给定的序列就地打乱,因此它不能是不可变的iterable,例如range。您需要提供list

修复代码的推荐方法是从range 创建一个list,将其传递给list 类型构造函数,即list(range(10))

num_arr = list(range(10))
random.shuffle(num_arr)

另一种(但不那么常见的)方法是使用列表推导:

num_arr = [n for n in range(10)]
random.shuffle(num_arr)

但是,请注意using list constructor could be much faster than using list comprehension

【讨论】:

  • 当普通的list(range(10)) 工作时,请不要建议使用无操作list 理解(尤其是在一个看起来像“答案”的大块中)。它只会延续一个常见的初学者错误,即不必要地使用list 推导式; list(range(10))正确的转换方式。
  • @ShadowRanger 公平评论。我已经更新了我的答案。
【解决方案2】:

random.shuffle 需要一个数字列表来随机播放,range(10) 没有提供。看看range(10) 返回的是什么:

num_arr = range(10)
num_arr
range(0, 10)

type(num_arr)
<class 'range'>

range() 不返回数字列表,它返回range 类型的对象。 range 对象是惰性可迭代对象(不是 iterators),它们在创建时不会生成其输出。您需要访问 range 对象中的值,方法是使用 for 循环对其进行循环,或者使用 list 一次将其全部转换为列表

list(num_arr)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

【讨论】:

    【解决方案3】:

    shuffle 函数需要传递一个列表,并且 range 函数更像是一个生成器。为了看到这一点,我们将创建自己的my_range 函数来复制 range 函数并尝试将其传递给 shuffle,你会得到一个类似的错误。

    import random
    
    def my_range(num: int):
        begin = 0
        while begin < num:
            yield begin
            begin += 1
    
    f = random.shuffle(my_range(10))
    

    【讨论】:

      猜你喜欢
      • 2018-01-10
      • 2018-05-11
      • 1970-01-01
      • 2021-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-15
      相关资源
      最近更新 更多