如何改变在function 中改变 input (list)

muench 发布于 2017年03月28日
无人欣赏。

本人是名学生,希望请教如何改变在function中的input_list, mutate the list.

def cycle(input_list):
    input_list=input_list.copy()
    first_num=input_list[0]
    input_list=input_list[1:]
    input_list.append(first_num)
    return input_list

#望在terminal 中希望得到的效果
>>> l = [1, 2, 4, 5, 'd']
>>> cycle(l)
>>> l
[2, 4, 5, 'd', 1]
>>> cycle(l)
>>> l
[4, 5, 'd', 1, 2]

#而实际得到的效果
>>> l = [1, 2, 4, 5, 'd']
>>> cycle(l)
>>> l
[1, 2, 4, 5, 'd']
>>> cycle(l)
>>> l
[1, 2, 4, 5, 'd']  

现在这个方程无法全局改变 list 的内容,望请教究竟是哪里错了,有什么更好的方法。谢谢。

共18条回复
tinyfool 回复于 2017年03月28日
l = cycle(l)

不就好了么?尽量不要动函数改变全局变量的念头,这是万恶之源,也叫做,函数有副作用,函数可以返回正确的结果就对了。

muench 回复于 2017年03月28日

1楼 @tinyfool 您好,非常感谢您的回复。这是校内Course的问题,任何不是跟上面模式输出一致的function会被校内系统自动判为错误,所以不得以必须要改变全局变量。

tinyfool 回复于 2017年03月28日

2楼 @muench 你把题目要求贴出来看看?

用global关键词可以修改全局变量,你搜索一下怎么用吧

muench 回复于 2017年03月28日

3楼 @tinyfool 您好,谢谢您的答复。这是题目的原题: 因为不是已知list的名称,而是随机出现一个在Terminal 中 Write a function cycle(inputlist) that performs an "in-place" cycling of the elements of a list, moving each element one position earlier in the list. Here "in place" means the operation should be performed by mutating the original list, and your function should not return anything. Note that you may assume that inputlist is non-empty (i.e. contains at least one element)

For example:

>>> l = [1, 2, 4, 5, 'd']
>>> cycle(l)
>>> l
[2, 4, 5, 'd', 1]
>>> cycle(l)
>>> l
[4, 5, 'd', 1, 2]

之前上面的是本人的照题目写的代码,无法完成题目要求: 下面这个是本人一位同学mutate成功的代码情况:

   def cycle(input_list):
        input_list = input_list.copy()
        tmp = input_list[0]
        for i in range(0, len(input_list)-1):
            input_list[i] = input_list[i+1]
        input_list[-1] = tmp
        return input_list

希望请教两者代码之间为何一个可以mutate成功,另外一个无法。决定于一个list中的值是否在方程中被改变的主要因素为何? 谢谢。

pinxue 回复于 2017年03月29日

4楼 @muench

  1. 提问应该提供完整的信息,比如这是啥语言。
  2. 你没有好好听课。
  3. 你的代码给 input_list 这个参数赋了新值,这个是修改了栈上的一个变量,函数返回以后就没了。
  4. 能工作的代码,修改的是 inputlist 这个变量所引用的数组,inputlist 返回后没了,但是所引用的数组已经变了。
muench 回复于 2017年03月29日

5楼 @pinxue 您好,谢谢您的帮助。 语音的种类为python, 因为在tag中有输入python的标签所以忘记在标题中加上python,十分抱歉。根据您所提供的关键词,已找到相关的资料和解答,再次非常感谢您的帮助。

pinxue 回复于 2017年03月29日

@tinyfool 帖子里也要把 tag 显示一下才好呀

tinyfool 回复于 2017年03月29日

7楼 @pinxue 你自己看,明明显示了

tinyfool 回复于 2017年03月29日

4楼 @muench 你同学的那个代码看着很可疑,没道理可以走通有效果,你贴代码的时候,贴全一点,这样我可以扔到python里面去测试一下

pinxue 回复于 2017年03月30日

8楼 @tinyfool 还真有,我上下翻了几遍楞是没看着……

pinxue 回复于 2017年03月30日

9楼 @tinyfool 被那个那个 return 带沟里了吧。 for i in range(0, len(inputlist)-1): inputlist[i] = input_list[i+1]

像 Swift 那种集合类也传值的变态还是比较罕见的

tinyfool 回复于 2017年03月30日

11楼 @pinxue 关键是他那个copy

pinxue 回复于 2017年03月30日

12楼 @tinyfool 哈哈,我还没学过 python…… 看你了

董一凡 回复于 2017年03月30日

11楼 @pinxue C++ 的集合类也是传值的,至于为什么 Swift 也是,你可以考虑下什么是 Swift 有而 Python 没有的。这个设计其实是一个唯一的选择,不然会引起极大的混乱,比如 Swift 的早期版本。

pinxue 回复于 2017年03月30日

14楼 @董一凡 虽然多年不折腾了, stl 的印象里用不用值语义是程序员可控制的

董一凡 回复于 2017年03月30日

15楼 @pinxue 不可控,除非你用指针,表现方式正好和 Swift 一模一样。而 Python 的表现方式和 Java 比较接近,本质原因是语言设计导致的,并不是你说的奇葩。

pinxue 回复于 2017年03月30日

16楼 @董一凡 说得就是 vector vb = va; 和 vector * pb = pa; 有得选嘛。Swift 奇葩之处在于,虽然采用写时复制在语言设计层面确实更合理更一致,但不符合开发者对这一语法的直觉。

当然,更奇葩的是先采用了符合工程派直觉的实现,然后又改成理论派更喜欢的实现。

muench 回复于 2017年04月07日

9楼 @tinyfool 您好,谢谢。因为上周学校课程问题,没有及时查看回复。那份代码后经您提醒与同学查证,当时其误以为本人问的是同一个worksheet的第二份代码,所以给错了。而本人在没有实际运行测试过那份代码就贴出询问,十分抱歉。最后感谢您的提醒。谢谢您的帮助。

本帖有18个回复,因为您没有注册或者登录本站,所以,只能看到本帖的10条回复。如果想看到全部回复,请注册或者登录本站。

登录 或者 注册
[顶 楼]
|
|
[底 楼]
|
|
[首 页]