​​Python​​中的list和array的不同之处


       python中的list是python的内置数据类型,list中的数据类不必相同的,而array的中的类型必须全部相同。在list中的数据类型保存的是数据的存放的地址,简单的说就是指针,并非数据,这样保存一个list就太麻烦了,例如list1=[1,2,3,'a']需要4个指针和四个数据,增加了存储和消耗cpu。

      numpy中封装的array有很强大的功能,里面存放的都是相同的数据类型


1. list1=[1,2,3,'a']  
2. print list1
3.
4. a=np.array([1,2,3,4,5])
5. b=np.array([[1,2,3],[4,5,6]])
6. c=list(a) # array到list的转换
7. print a,np.shape(a)
8. print b,np.shape(b)
9. print c,np.shape(c)

运行结果:



1. [1, 2, 3, 'a'] # 元素数据类型不同,并且用逗号隔开  
2. [1 2 3 4 5] (5L,) # 一维数组,类型用tuple表示
3. [[1 2 3]
4. 4 5 6]] (2L, 3L)
5. [1, 2, 3, 4, 5] (5L,)


创建:


    array的创建:参数既可以是list,也可以是元组.使用对应的属性shape直接得到形状


1. a=np.array((1,2,3,4,5))# 参数是元组  
2. b=np.array([6,7,8,9,0])# 参数是list
3. c=np.array([[1,2,3],[4,5,6]])# 参数二维数组
4. print a,b,
5. c.shape()



   也可以直接改变属性array的形状,-1代表的是自己推算。这里并不是T, reshape(())也可以



​​


1. c = np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]])  
2. c.shape # (3L, 4L)
3. c.shape=4,-1 //c.reshape((2,-1))
4. c


    1. <pre style="box-sizing: border-box; overflow: auto; font-size: 14px; padding: 0px; margin-top: 0px; margin-bottom: 0px; line-height: 17.0001px; word-break: break-all; word-wrap: break-word; border: 0px; border-radius: 0px; white-space: pre-wrap; vertical-align: baseline; background-color: rgb(255, 255, 255);">array([[ 1,  2,  3],  
    2. 4, 4, 5],
    3. 6, 7, 7],
    4. 8, 9, 10]])




    这里的reshape最终相当于是一个浅拷贝,也就是说还是和原来的书c使用相同的内存空间
    [python] 
    view plain
    copy

    print
    ?



    d=c.reshape((2,-1))

    d[1:2]=100

    c



    array([[ 1, 2, 3],
    [ 4, 4, 5],
    [100, 100, 100],
    [100, 100, 100]])
    前面在创建数组的时候并没有使用数据类型,这里我们也可以使用数据类型。默认的是int32.
    [python] 
    view plain
    copy

    print
    ?



    a1=np.array([[1,2,3],[4,5,6]],dtype=np.float64)

    print a1.dtype,a.dtype #float64 int32<pre style="margin-top: 0px; margin-bottom: 0px; line-height: 17.0001px; box-sizing: border-box; overflow: auto; font-size: 14px; padding: 0px; word-break: break-all; word-wrap: break-word; border: 0px; border-radius: 0px; white-space: pre-wrap; vertical-align: baseline; background-color: rgb(255, 255, 255);">

    前面在创建的时候我们都是使用的np.array()方法从tuple或者list转换成为array,感觉很是费劲,numpy自己提供了很多的方法让我们自己直接创建一个array



    [python] 
    view plain
    copy

    print
    ?



    arr1=np.arange(1,10,1) #

    arr2=np.linspace(1,10,10)

    print arr1,arr1.dtype

    print arr2,arr2.dtype


    [1 2 3 4 5 6 7 8 9] int32
    [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.] float64
    np.arange(a,b,c)表示产生从a-b不包括b,间隔为c的一个array,数据类型默认是int32。但是linspace(a,b,c)表示的是把a-b平均分成c分,它包括b。
    有时候我们需要对于每一个元素的坐标进行赋予不同的数值,可以使用fromfunction函数




    [python]
    view plain
    copy

    print
    ?



    def fun(i):

    return i%4+2

    np.fromfunction(fun,(10,))



    array([ 2., 3., 4., 5., 2., 3., 4., 5., 2., 3.]) fromfunction必须支持多维数组,所以他的第二个参数必须是一个tuple,只能是(10,),(10)是错误的。




    [python]
    view plain
    copy

    print
    ?



    def fun2(i,j):

    return (i+1)*(j+1)

    np.fromfunction(fun2,(9,9))



    array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9.],
    [ 2., 4., 6., 8., 10., 12., 14., 16., 18.],
    [ 3., 6., 9., 12., 15., 18., 21., 24., 27.],
    [ 4., 8., 12., 16., 20., 24., 28., 32., 36.],
    [ 5., 10., 15., 20., 25., 30., 35., 40., 45.],
    [ 6., 12., 18., 24., 30., 36., 42., 48., 54.],
    [ 7., 14., 21., 28., 35., 42., 49., 56., 63.],
    [ 8., 16., 24., 32., 40., 48., 56., 64., 72.],
    [ 9., 18., 27., 36., 45., 54., 63., 72., 81.]]) 虽然说,这里提供了很多的直接产生array的方式,但是大部分情况我们都是会从list进行转换,因为在实际的处理中,我们需要从txt加载文件,那样直接读入的数据显示存放到list中,需要处理的时候我们转换到array,因为array的设计更加符合我们的使用,涉及到矩阵的运算在使用mat,那么list主要就是用进行元素的索取。




    [python]
    view plain
    copy

    print
    ?



    def loaddataSet(fileName):

    file=open(fileName)

    dataMat=[] //

    for line in file.readlines():

    curLine=line.strip().split('\t')

    floatLine=map(float,curLine)//这里使用的是map函数直接把数据转化成为float类型

    dataMat.append(floatLine)

    return dataMat



    上面的韩顺返回最终的数据就是最初的list数据集,再根据不同的处理需求是转化到array还是mat。其实array是mat的父类,能用mat的地方,array理论上都能传入。


    元素访问:









    [python]
    view plain
    copy

    print
    ?



    arr[5] #5

    arr[3:5] #array([3, 4])

    arr[:5] #array([0, 1, 2, 3, 4])

    arr[:-1]# array([0, 1, 2, 3, 4, 5, 6, 7, 8])

    arr[:] #array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

    arr[2:4]=100 # array([ 0, 1, 100, 100, 4, 5, 6, 7, 8, 9])

    arr[1:-1:2] #array([ 1, 100, 5, 7]) 2 是间隔

    arr[::-1] #array([ 9, 8, 7, 6, 5, 4, 100, 100, 1, 0])

    arr[5:2:-1]# -1的间隔表示从右向左所以5>2 #array([ 5, 4, 100])








    上面是array的一维数组的访问方式,我们再来看看二维的处理方式



    [python]
    view plain
    copy

    print
    ?



    print c[1:2]# c[1:2].shape-->(1L, 3L)

    print c[1:2][0] # shape-->(3L,)



    [[4 4 5]]
    [4 4 5]




    [python]
    view plain
    copy

    print
    ?



    print c[1]

    print c[1:2]



    [4 4 5]
    [[4 4 5]]




    [python]
    view plain
    copy

    print
    ?



    print c[1][2]

    print c[1:4]

    print c[1:4][0][2]



    5
    [[ 4 4 5]
    [100 100 100]
    [100 100 100]]
    5
    可以看出对于有:的表达最终的结果外面还嵌套一层list的[],。访问的一定要注意,python最bug的就是,语法灵活,不管怎样写索引语法都是正确的,但是最终的书结果却让你大跌眼镜。
    还有array的索引最终产生的是一个一个原始数据的浅拷贝,还和原来的数据共用一块儿内存




    [python]
    view plain
    copy

    print
    ?



    b=arr[1:6]

    b[:3]=0

    arr #<pre style="box-sizing: border-box; overflow: auto; font-size: 14px; padding: 0px; margin-top: 0px; margin-bottom: 0px; line-height: 17.0001px; word-break: break-all; word-wrap: break-word; border: 0px; border-radius: 0px; white-space: pre-wrap; vertical-align: baseline; background-color: rgb(255, 255, 255);">array([0, 0, 0, 0, 4, 5, 6, 7, 8, 9])


    产生上面的原因是因为array中直接存放的数据,拷贝的话直接拿走的是pointer,没有取走数据,但是list却会直接发生深拷贝,数据指针全部带走



    [python]
    view plain
    copy

    print
    ?



    list1=list(c)

    list1[1]=0

    list1 #上面修改的0并没有被改变



    [array([1, 2, 3]), 0, array([100, 100, 100]), array([100, 100, 100])]


    除了这些之外还有自己的更加牛掰的方式(只能用array) 1)使用布尔数组.感觉甚是强大,就不要自己写什么判断语句啦,注意这种方式得到结果不和原始数组共享空间。布尔索引仅仅适用于数组array,list没资格用。布尔索引最终得到下标索引为true的数据。索引只能是布尔数组



    [python]
    view plain
    copy

    print
    ?



    a=np.array(a*2)

    a>5

    a[a>5] #



    array([16, 32, 48, 64, 80, 16, 32, 48, 64, 80])

    2)列表索引
    列表索引可以是数组和list。返回的数据不和原来的数据共享内存。索引可以是list和array



    [python]
    view plain
    copy

    print
    ?



    x=np.arange(10)

    index=[1,2,3,4,5]

    arr_index=np.array(index)

    print x

    print x[index] # list索引

    print x[arr_index] # array索引



    [0 1 2 3 4 5 6 7 8 9]
    [1 2 3 4 5]
    [1 2 3 4 5]
    array和list区别*2



    [python]
    view plain
    copy

    print
    ?



    a=np.arange(10)

    lista=list(a)

    print a*2

    print lista*2



    [ 0 2 4 6 8 10 12 14 16 18]
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


    array的广播










    [python]
    view plain
    copy

    print
    ?



    a = np.arange(0, 60, 10).reshape(-1, 1)

    b = np.arange(0, 5)

    print a

    print b



    [[ 0]
    [10]
    [20]
    [30]
    [40]
    [50]]
    [0 1 2 3 4]




    [python]
    view plain
    copy

    print
    ?


    print np.add(a,b,c)



    [[ 0 1 2 3 4]
    [10 11 12 13 14]
    [20 21 22 23 24]
    [30 31 32 33 34]
    [40 41 42 43 44]
    [50 51 52 53 54]]