python list的+,+=,append,extend
面试题之中的一个。
def func1(p):
p = p + [1] def func2(p):
p += [1] p1 = [1,2,3]
p2 = [1,2,3]
func1(p1)
func2(p2)
print p1
print p2
结果:
我以为像这样的传參作为局部变量。由于都不会影响外部的list。所以答案应该是p1 =[1,2,3] ,p2=[1,2,3],然而
>>>
[1, 2, 3]
[1, 2, 3, 1]
>>>
重新被面试官虐杀,不甘心的我查找了python 局部变量:
x = [1,2,3] def func(x):
print "local! original x = ",x
x = [1]
print "local! now x = ",x func(x)
print "global! x = ",x
结果:
local! original x = [1, 2, 3]
local! now x = [1]
global! x = [1, 2, 3]
没错啊。我还记得要用全局变量得加global x 之类的语句呢。
为了保险起见,加一个id(),查查看对象是不是同一个先:
x = [1,2,3]
print "before func(), global! x = ",x,"id(x) = ",id(x) def func(x):
print "in func(), local! original x = ",x,"id(x) = ",id(x)
x = [1]
print "in func(), local! now x = ",x,"id(x) = ",id(x) func(x)
print "after func(), global! x = ",x,"id(x) = ",id(x)
结果:
before func(), global! x = [1, 2, 3] id(x) = 46798728
in func(), local! original x = [1, 2, 3] id(x) = 46798728
in func(), local! now x = [1] id(x) = 46789512
after func(), global! x = [1, 2, 3] id(x) = 46798728
恩,能够看到,全局变量中的id(x) = 46798728,x进到func()中,由于运行了x = [1],才变成id(x) = 46789512。(合情合理)
这也说明python的确是传引用入函数。(然并卵)
利用id(x),查看下x = x + [1]对象是怎么变化的吧:
x = [1,2,3]
print "before func(), global! x = ",x,"id(x) = ",id(x) def func(x):
print "in func(), local! original x = ",x,"id(x) = ",id(x)
x = x + [1]
print "in func(), local! now x = ",x,"id(x) = ",id(x) func(x)
print "after func(), global! x = ",x,"id(x) = ",id(x)
结果:
before func(), global! x = [1, 2, 3] id(x) = 46339976
in func(), local! original x = [1, 2, 3] id(x) = 46339976
in func(), local! now x = [1, 2, 3, 1] id(x) = 46390664
after func(), global! x = [1, 2, 3] id(x) = 46339976
啊。x = x + [1],是新建了一个对象,id(x) = 46390664。
利用id(x),查看下x += [1]对象是怎么变化的吧:
x = [1,2,3]
print "before func(), global! x = ",x,"id(x) = ",id(x) def func(x):
print "in func(), local! original x = ",x,"id(x) = ",id(x)
x += [1]
print "in func(), local! now x = ",x,"id(x) = ",id(x) func(x)
print "after func(), global! x = ",x,"id(x) = ",id(x)
结果:
before func(), global! x = [1, 2, 3] id(x) = 46536584
in func(), local! original x = [1, 2, 3] id(x) = 46536584
in func(), local! now x = [1, 2, 3, 1] id(x) = 46536584
after func(), global! x = [1, 2, 3, 1] id(x) = 46536584
啊,id(x)全程一样。x += [1],python直接就在原对象上操作,还真是够懒的说。
利用id(x),查看下x.append([1])对象时怎样变化的吧:
x = [1,2,3]
print "before func(), global! x = ",x,"id(x) = ",id(x) def func(x):
print "in func(), local! original x = ",x,"id(x) = ",id(x)
x.append([1])
print "in func(), local! now x = ",x,"id(x) = ",id(x) func(x)
print "after func(), global! x = ",x,"id(x) = ",id(x)
结果:
before func(), global! x = [1, 2, 3] id(x) = 47191944
in func(), local! original x = [1, 2, 3] id(x) = 47191944
in func(), local! now x = [1, 2, 3, [1]] id(x) = 47191944
after func(), global! x = [1, 2, 3, [1]] id(x) = 47191944
啊,id(x)全程一样,看来list的属性方法都是在原对象上操作的吧,我记得list.sort()也是,待会要验证的list.extend()预计也是。
利用id(x),查看下x.extend([1])对象时怎样变化的吧:
x = [1,2,3]
print "before func(), global! x = ",x,"id(x) = ",id(x) def func(x):
print "in func(), local! original x = ",x,"id(x) = ",id(x)
x.extend([1])
print "in func(), local! now x = ",x,"id(x) = ",id(x) func(x)
print "after func(), global! x = ",x,"id(x) = ",id(x)
结果:
before func(), global! x = [1, 2, 3] id(x) = 48437128
in func(), local! original x = [1, 2, 3] id(x) = 48437128
in func(), local! now x = [1, 2, 3, 1] id(x) = 48437128
after func(), global! x = [1, 2, 3, 1] id(x) = 48437128
果然id(x)全程一样。
话说list.append()是追加,extend()是拓展,他们的差别大概就是:
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> c = [7,8,9]
>>> a.append(b)
>>> a
[1, 2, 3, [4, 5, 6]]
>>> c.extend(b)
>>> c
[7, 8, 9, 4, 5, 6]
>>>
看了上面的几段代码,聪明的你应该也能看出来:
list1 += list2 等价于 list1.extend(list2),这是证据:
源码地址: view=markup">http://svn.python.org/view/python/trunk/Objects/listobject.c? view=markup
913 static PyObject *
914 list_inplace_concat(PyListObject *self, PyObject *other)
915 {
916 PyObject *result;
917
918 result = listextend(self, other); //+=果然用了listextend()
919 if (result == NULL)
920 return result;
921 Py_DECREF(result);
922 Py_INCREF(self);
923 return (PyObject *)self;
924 }
利用id(x)。查看下global x下。对象的变化吧:
x = [1,2,3]
print "before func(), global! x = ",x,"id(x) = ",id(x) def func():
global x
print "in func(), local! original x = ",x,"id(x) = ",id(x)
x = x + [1]
print "in func(), local! now x = ",x,"id(x) = ",id(x) func()
print "after func(), global! x = ",x,"id(x) = ",id(x)
结果:
before func(), global! x = [1, 2, 3] id(x) = 47781768
in func(), local! original x = [1, 2, 3] id(x) = 47781768
in func(), local! now x = [1, 2, 3, 1] id(x) = 47795720
after func(), global! x = [1, 2, 3, 1] id(x) = 47795720
啊,global就保证了,即使我的变量x在函数中指向对象变了,外部的x也会指向新的对象。
回到面试题:
def func1(p):
p = p + [1] def func2(p):
p += [1] p1 = [1,2,3]
p2 = [1,2,3]
func1(p1)
func2(p2)
print p1
print p2
p1传入func1()。由于+操作,生成一个新的对象。但没有return给外部的p1。所以外部的p1=[1,2,3]。
p2传入func2(),由于+=操作,就是list.extend()。操作。在原对象操作。所以p2=[1,2,3,1]。
吐槽下:
事实上python在函数中參数是传引用的,假设一个对象obj进到函数中,被改变,那不管在哪里这个obj就是被改变了。并没有什么副本什么的。
那为什么有些时候看起来。函数中obj怎么被改变,外部的obj都岿然不动,啊,由于这个被改变后的obj不是原来的它了。
比方x = x + [1]。新的x真的是原来传进来的x吗?不是的。
此时的x是新的对象了(看id就知道了)。先前传进来的x。并没有被改变。
一点浅见,求打脸。
总结:
1、list + 创建一个新的对象。
2、list的 += 和 list.extend(),等价。都是在原对象上操作。
3、list.append()。也是在原对象上操作。
4、global,全局变量,嗯,不错(这算什么总结嘛)。
python list的+,+=,append,extend的更多相关文章
- [python][oldboy]list append, extend
# coding=utf8 li = [1, 3, [1, "liu"], "liu"] print li li.append([1, 2]) print li ...
- python列表插入--append(), extend(), insert()
append(),extend(), insert()都是列表操作中常用的插入函数.其中前两个均接收一个参数,并插入到列表尾部.最后一个接收两个参数,将参数2插入到参数1之前. 本文主要讨论appen ...
- Python sys.path.append
python sys.path.append 对于模块和自己写的程序不在同一个目录下,可以把模块的路径通过sys.path.append(路径)添加到程序中. 在程序开头加上: import syss ...
- python 之 append extend
概述 append和extend针对python的列表 列表内的元素为对象,可以为数字.字符串.列表等等 append添加的是一个对象 extend添加一个列表 例子 append >>& ...
- python中List append()、extend()和insert()的区别
Python中向列表增加更多数据时,有append().extend()和insert()等方法 其中最常用的是list.append(obj) 向列表的尾部添加一个新的元素. 需要一次性添加多个元素 ...
- python list中append()方法和extend()方法区别
共同点 只能作用于list类型(不能作用于tuple等其他类型) 单参数限制(不支持多参数) 不同点 list.append(object) 向列表中添加一个对象object. 使用append的时候 ...
- python list成员函数extend与append的区别
extend 原文解释,是以list中元素形式加入到列表中 extend list by appending elements from the iterable append(obj) 是将整个ob ...
- python append extend区别
1. 列表可包含任何数据类型的元素,单个列表中的元素无须全为同一类型. 2. append() 方法向列表的尾部添加一个新的元素. 3. 列表是以类的形式实现的.“创建”列表实际上是将一个类实例化.因 ...
- python list中append()与extend()用法
列表是以类的形式实现的.“创建”列表实际上是将一个类实例化.因此,列表有多种方法可以操作. 1. 列表可包含任何数据类型的元素,单个列表中的元素无须全为同一类型. 2. append() 方法向列表的 ...
- python列表之append与extend方法比较
append和extend是列表的两种添加元素方式,但这两种方式却又有些不同之处.那么不同之处在哪里呢,我们通过对二者的定义和实例来看一看. list.append() 1.定义:L.append(o ...
随机推荐
- 路飞学城Python-Day9
[23.函数-高阶函数]变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称为高阶函数如果一个函数可以接收另一个函数,这个函数就称为高阶函数 def func ...
- wordpress 后台登录增加访问效验,优化退出效果
之前记录了 wordpress 后台登录增加访问效验, 记录了增加后台访问地址被直接访问的困难性的修改步骤. 还有一个地方需要补充一下,就是退出. 退出的时候不做调整会直接跳到首页,这样体验很不好. ...
- ESRI.ArcGIS.Controls.AxMapControl
今天在写DLL时发现,直接引用ESRI.ArcGIS.Controls,发现AxMapControl的参数仍然不好用,后来发现,需要引用ESRI.ArcGIS.AxControls这个DLL.而且还需 ...
- [Angular] Short Imports with TypeScript Path Mapping
The idea is change from: import {CoreModule} from '../core/core.module'; to: import {CoreModule} fro ...
- [Angular] Configure an Angular App at Runtime
It always again happens (especially in real world scenarios) that you need to configure your Angular ...
- google在线測试练习题3
Problem The Latin alphabet contains 26 characters and telephones only have ten digits on the keypad. ...
- oracle 11g RAC手动卸载grid,no deinstall
1.通过root用户进入到grid的ORACLE_HOME [root@db01]# source /home/grid/.bash_profile [root@db01]# cd $ORACLE_H ...
- Spring MVC模式示例(采用解耦控制器)
Product package com.mstf.bean; import java.io.Serializable; /** * Product类,封装了一些信息,包含三个属性 * @author ...
- 日前加拿大平板厂商 Datawind和印度运营商Reliance Communications日前宣布合作
全球最便宜智能手机只要15美元 随着手机进入智能时代,这些年智能手机的发展可谓迅猛,苹果三星这样的手机厂商成为最大的受益者同时,低门槛也让越来越多的人开始意识到,全民智能时代确实要来了. 为了能让第三 ...
- 将double数据保留两位小数
private double formatDouble(double number) { DecimalFormat df = new DecimalFormat("#.00"); ...