代码之家  ›  专栏  ›  技术社区  ›  Dewfy

改进Python列表切片

  •  0
  • Dewfy  · 技术社区  · 15 年前

    要用最后一个元素构建列表所有组合的字符串,我想写一个简单的:

    for i in range(l, 0, -1):
        yield " ".join(src[0:i-1].append(src[-1]))
    

    但我有: TypeError . 而是使用以下带有中间变量的代码:

     for i in range(l, 0, -1):
            sub = src[0:i-1]
            sub.append(src[-1])
            yield " ".join(sub)
    

    5 回复  |  直到 9 年前
        1
  •  8
  •   Alex Martelli    15 年前

    Python中的变异方法不返回对已变异对象的引用的原因可以在 Command-Query Separation 原则(简称CQS)。Python没有像Meyer的Eiffel语言那样彻底地应用CQS(因为——根据Python的Zen,又名 import this ,“实用性胜过纯度”):例如, somelist.pop() 返回刚刚弹出的元素(仍然不是刚刚变异的容器;-),而在Eiffel弹出堆栈时没有返回值(在需要弹出并使用top元素的常见情况下,首先使用“查询”查看顶部,然后使用“命令”使顶部消失)。

    CQS的深层动机并不是真正的“变种应该不会返回任何有用的东西”:而是“查询应该没有副作用”。保持这种区别(无论是严格的还是“作为一种指导原则而不是规则”)应该有助于你记住它,而且它在某种程度上确实起作用(捕捉到一些意外错误),尽管如果你习惯了流畅的“表达式和语句是一样的”语言,有时会感到不方便。

    Python中CQS(广义地说…)的另一个方面是语句和表达式之间的区别。同样,这并不是严格应用的——表达式可以在任何语句可以使用的地方使用,这偶尔会隐藏错误,例如,当有人忘记调用他们需要的函数时 foo() ,不只是 foo ;-). 但是,例如(与C、Perl等截然不同),您不能在测试的同时轻松地分配某些内容( if(a=foo())... ),这有时会带来不便,但会捕获其他类型的意外错误。

        2
  •  7
  •   Rafał Dowgird    15 年前

    嗯,也许可以替换:

    src[0:i-1].append(src[-1])
    

    src[0:i-1] + src[-1:] #note the trailing ":", we want a list not an element
    
        3
  •  1
  •   Hank Gay    15 年前

    一般的理由是返回类型为 None 指示 list 正在进行适当的修改。

        4
  •  0
  •   SilentGhost    15 年前
    for i in range(l-1, 0, -1):
        yield ' '.join(src[:i] + src[-1:])
    

    扩展/追加方法就地修改列表,因此不返回列表。

        5
  •  -1
  •   u0b34a0f6ae    15 年前

    or 结构:

    def append_and_return(li, x):
      """silly example"""
      return (li.append(x) or li)
    

    X or Y 计算X,如果X为真,则返回X,否则计算并返回Y。X需要始终为负。

    >>> li = [1, 2, 3]
    >>> newli = append_and_return(li, 10)
    >>> li
    [1, 2, 3, 10]
    >>> newli is li
    True