【问题标题】:Appending to range function附加到范围函数
【发布时间】:2013-11-29 21:21:14
【问题描述】:

编辑:感谢您对如何完成我正在尝试做的事情的友好回复,但问题是关于 WHY range().append() 返回如果您一步尝试,则没有,为什么如果您分两步尝试,它会起作用。

我正在尝试创建一个数字列表,但有一点不同。我不想在我的列表开头出现几个数字:

mlist = [0, 5, 6, 7, ...]

所以我想这样做:

 mlist = range(5,n+1).append(0)

但静默失败,因为 type(mlist) 之后等于 NoneType ?! (相关:type(range(5,10) 评估为 list 类型)

如果我尝试分两步进行,例如:

>>> mlist = range(5,10)
#and then
>>> mlist.append(0)
>>> mlist
[5, 6, 7, 8, 9, 10, 0]

发生了什么事?

【问题讨论】:

  • 我对最后一个 sn-p 有点怀疑。 :^) 你应该得到一个mlist[5, 6, 7, 8, 9, 0],而且间距是错误的。请复制并粘贴成绩单——否则很容易出错。
  • @DSM 你是对的,我的目标是一个快速的例子来说明两步移动的工作原理:)
  • 我确实解释了为什么;因为.append() 改变了列表。这也让你质疑重复。

标签: python python-2.x


【解决方案1】:

有多种选择,但最简单的一种可能是:

>>> mlist = [0] + range(5,10)
>>> mlist
[0, 5, 6, 7, 8, 9]

要在开头插入一个项目,请使用 list.insert0(索引 0):

>>> mlist = range(5,10)
>>> mlist.insert(0, 0) # the first 0: index, the second 0: the item to insert
>>> mlist
[0, 5, 6, 7, 8, 9]

编辑答案

大多数更改序列/映射的方法返回None。所以只需调用方法,不要将返回值重新赋值给变量。

请参阅 Python 常见问题解答中的 Why doesn’t list.sort() return the sorted list?

【讨论】:

    【解决方案2】:

    list.append() 更改列表就地,并返回None。通过分配您将该返回值分配给mlist,而不是您想要构建的列表。这是一个标准的 Python 习语;改变可变对象的方法永远不会返回改变的对象,总是None

    两步分开:

    mlist = range(5, n + 1)
    mlist.append(0)
    

    这会将[0] 添加到结束;如果您在开始时需要0,请使用:

    mlist = [0] + range(5, n + 1)
    

    或者您可以使用list.insert(),再次作为单独的调用:

    mlist = range(5, n + 1)
    mlist.insert(0, 0)
    

    但后者必须将所有元素向上移动一步,通过连接创建一个新列表对于较短的列表是更快的选择,在较长的列表中插入获胜:

    >>> from timeit import timeit
    >>> def concat(n):
    ...     mlist = [0] + range(5, n)
    ... 
    >>> def insert(n):
    ...     mlist = range(5, n)
    ...     mlist.insert(0, 0)
    ... 
    >>> timeit('concat(10)', 'from __main__ import concat')
    1.2668070793151855
    >>> timeit('insert(10)', 'from __main__ import insert')
    1.4820878505706787
    >>> timeit('concat(1000)', 'from __main__ import concat')
    23.53221583366394
    >>> timeit('insert(1000)', 'from __main__ import insert')
    15.84601092338562
    

    【讨论】:

    • 为什么不从insert开始呢?
    • 因为你将所有元素上移一个位置;不妨创建一个新列表。
    【解决方案3】:

    编辑:感谢您对如何完成我正在尝试做的事情的友好回复,但问题是如果您一步尝试,为什么 range().append() 会返回 None,为什么它会起作用,如果你分两步走。

    简单地说——GvR 不喜欢它——来自Python developers mailing list

    我想再次解释一下为什么我如此坚持 sort() 不应该 返回“自我”。

    这来自一种编码风格(在其他各种语言中很流行,我 相信尤其是 Lisp 陶醉于其中)其中一系列副作用 在单个对象上可以像这样链接:

    x.compress().chop(y).sort(z)

    这将与

    相同

    x.compress()
    x.chop(y)
    x.sort(z)

    我发现链接形式对可读性构成威胁;它要求 读者必须非常熟悉每种方法。这 第二种形式清楚地表明,这些调用中的每一个都作用于相同的 对象,所以即使你不太了解类及其方法 好吧,您可以理解第二个和第三个调用适用于 x (并且所有调用都是为了它们的副作用),而不是 别的东西。

    我想为返回新值的操作保留链接, 比如字符串处理操作:

    y = x.rstrip("\n").split(":").lower()

    有一些标准库模块鼓励链接 副作用调用(想到 pstat)。应该没有新的 那些;当 pstat 很弱时,它会通过我的过滤器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-15
      • 1970-01-01
      • 1970-01-01
      • 2017-09-24
      • 2020-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多