zoukankan      html  css  js  c++  java
  • python把列表(list)传给函数形参时的问题剖析

    python把列表(list)传给函数形参时的问题剖析

     国内图书很大一部分关于“列表传递给函数”的问题避重就轻,有的甚至不会提及"列表传参"的问题,业界强推的《流畅的python》一书有提及,且有专门的分析,另外,梁勇《python程序设计》也有类似分析,但是笔者感觉解释的还是不够通透,有必要重新剖析,

    如果您是高手,请晒出您的评论留言,给出您的见解和剖析, 不胜感激.


    预期结果

    1 ---1---
    2 [0, 1, 4, 9]
    3 ---2---
    4 [0, 1, 4, 9, 16]

    实际执行结果

    1 ---1---
    2 [0, 1, 4, 9]
    3 ---2---
    4 [0, 1, 4, 9, 0, 1, 4, 9, 16]

    出坑


     

    当定义函数时,会保存函数中默认参数 list 的值,也就是列表 li=[];

    在每次调用的时候如果传递了新的列表,则使用传递的列表,没有传递,使用定义函数时保存的默认参数(li=[]);

    上面两次调用中,都没有传递新的列表(使用默认列表 li=[] ),程序会调用定义函数时保存的默认参数((li=[]));

    列表在append的时候会在 li=[] 原来的基础上append追加值,所以会产生以上结果.

    通过打印列表的ID进行辨识

    打印列表 li=[] 的ID:

     1 def f(x,li=[]):
     2     print(id(li))  # 添加打印id
     3     for i in range(x):
     4         li.append(i*i)
     5     print(li)
     6  
     7  
     8 print('---1---')
     9 f(4)
    10 print('---2---')
    11 f(5)

    结果:

    1 ---1---
    2 140306123906248
    3 [0, 1, 4, 9]
    4 ---2---
    5 140306123906248
    6 [0, 1, 4, 9, 0, 1, 4, 9, 16]

    会发现ID值是相同的;  说明两次执行时使用的都是定义函数时的默认参数 li=[ ]

    执行时往里面传新的列表

    打印列表 li=[] 的ID 和 传的新列表的ID:

     1 def f(x,li=[]):
     2     print(id(li))
     3     for i in range(x):
     4         li.append(i*i)
     5     print(li)
     6  
     7  
     8 print('---1---')
     9 f(4)
    10 print('---2---')
    11 f(5,[])
    12 print('---3---')
    13 f(6)

    结果:

    1 ---1---
    2 [0, 1, 4, 9]
    3 ---2---
    4 [0, 1, 4, 9, 16]
    5 ---3---
    6 [0, 1, 4, 9, 0, 1, 4, 9, 16, 25]

    会发现执行传递空(新)列表的函数时打印的ID不一样,而没有传递的一样;

    当传递空列表时,函数体当中会使用传递的空列表,没有传递时,使用函数默认值 li=[ ], 所以会产生以上结果。

    优化


     

    如果想要达到预期的结果,只需要在函数体里进行判断即可:

     1 def f(x, li=[]):
     2     if not li:
     3         # 如果li不为空的话,就往下走(清空列表); 为空就不走
     4         li = []
     5     for i in range(x):
     6         li.append(i * i)
     7     print(li)
     8 
     9 
    10 print('---1---')
    11 f(4)
    12 print('---2---')
    13 f(5)
    14 print('---3---')
    15 f(6)

    结果:

    1 ---1---
    2 [0, 1, 4, 9]
    3 ---2---
    4 [0, 1, 4, 9, 16]
    5 ---3---
    6 [0, 1, 4, 9, 16, 25]

     ----over----

    福利赠送: 代码运行自动可视化网站,强烈推荐,不懂就把代码扔进去,它会一步步教给您代码运行的过程。

    网址: http://pythontutor.com/

     

    参考修改:https://www.cnblogs.com/gpd-Amos/p/8998059.html

  • 相关阅读:
    sqlite数据库的char,varchar,text,nchar,nvarchar,ntext的区别(转)
    DELPHI XE5-8 弹出列表框供选择
    delphi弹出选择对话框选择目录|SelectDirectory 函数(转)
    php 与java安卓客户端的查询交互
    sql查询语句的拼接小技巧(高手勿喷)
    高德地图应用——与云图后台交互
    Inno Setup 通用脚本及简要说明( 一般情况够用了)
    不用SQL给打印记录编号
    DELPHI XE5/6/7 android 无线真机调试
    超级简单的例子说明JAVA PACKET CLASS 和变量之间的关系
  • 原文地址:https://www.cnblogs.com/tsingke/p/14348025.html
Copyright © 2011-2022 走看看