在python或coffeescript中,为什么list.append不返回列表本身?如果是这样,递归可以简单得多
如果insert()返回列表本身,请考虑以下代码在python或coffeescript中,为什么list.append不返回列表本身?如果是这样,递归可以简单得多,python,functional-programming,coffeescript,Python,Functional Programming,Coffeescript,如果insert()返回列表本身,请考虑以下代码 def sieve(l): if not len(l): return [] return sieve(filter(lambda x: x%l[0] != 0, l)).insert(0, l[0]) 现在,我们必须依靠helper函数在插入后返回列表 def cons(a, l): l.insert(0, a) return l def sieve(l): if not len(l): return [
def sieve(l):
if not len(l):
return []
return sieve(filter(lambda x: x%l[0] != 0, l)).insert(0, l[0])
现在,我们必须依靠helper函数在插入后返回列表
def cons(a, l):
l.insert(0, a)
return l
def sieve(l):
if not len(l):
return []
return cons(l[0], sieve(filter(lambda x:x%l[0] != 0, l)))
可变/不可变对象的点是完全有效的
然而,对于可变的列表,IMHO,append()API可以采取更多步骤来返回列表本身,而不是不返回任何内容。Java StringBuilder就是一个很好的例子。我可以递归地在stringbuilder对象上进行链式追加……但愿我们在这里也能做到这一点。在Python中,让初学者了解哪些对象是“不可变”且不能更改的,哪些对象是“可变”且可以更改的是一件大事,在后一种情况下,对对象的每个引用都会看到相同的更改。这似乎真的让新来者感到困惑。“我天真地调用了我编写的这个函数,突然我的列表副本也改变了!” 因此Python有一个约定:不可变对象,当您要求它们进行调整时,返回新创建的对象作为答案-因此:
a = 'my string'
b = a.replace('y', 'e')
使b
获取一个全新的字符串,而a
保留其原始值。显然,这样的方法必须返回一个值,因为通过检查原始的、不可变的对象本身,您永远看不到更改
但是当你要求一个可变对象改变它自己时,它不会返回它自己,因为它不需要——你只需再次查看原始对象就可以看到改变!在Python中,这是一个关键的语义信号:如果像
append()
这样的方法没有返回新对象,那么您只需查看旧对象就可以看到更改,引用旧对象的其他人也可以看到更改。为什么不创建一个引用呢?我认为这也会使代码更具可读性。因为您询问了CoffeeScript
push
方法在适当的位置修改数组。它不会返回新修改的数组,而是返回刚才添加的值。当然,这是不直观的,但它可能是有用的。例如,你可以写这样的东西
getNewValue -> cache.push fetchValue()
它在一行中获取一个值,将其添加到缓存
,并从getNewValue
返回该值
另一方面,concat
方法不修改原始数组,而是返回修改后的副本。它应该用于连接两个数组,但非数组值将被强制,因此如果需要,可以将其用作push
替换:
arr = [1, 2, 3]
arr = arr.concat 4
console.log arr # [1, 2, 3, 4]
关于JavaScript数组方法的完整文档是可用的。我想如果有人认为他们可以使用
b=a.append(0)
,而没有意识到现在a就是b
,可能会引起很多混乱。您的列表对象上必须已经有一个引用才能调用绑定方法。append
,这样您就不需要将对它的另一个引用返回给您。我不知道这与CoffeeScriptgood Response有什么关系。使用x=[1,2]
,比较并对比x.sort()
和sorted(x)
,注意sorted(x)==x和sorted(x)不是x
。