zoukankan      html  css  js  c++  java
  • 列表及相关操作的总结

    1、 如何来进行对象的拷贝

    在进行对象拷贝的时候,一不小心就会变成了对象引用,在赋值的时候使用的是引用,而在其他的例如a=【】的时候是对象的绑定。

    >>> list1
    ['kel', 2]
    >>> list2 = list1
    >>> list2
    ['kel', 2]
    >>> list2[0]='changed list 2'
    >>> print list1,list2
    ['changed list 2', 2] ['changed list 2', 2]
    在将list1赋值给list2的时候,然后修改其中一个值,那么两个都会发生改变,因为在这种情况,两者都是引用,只是绑定了不同的变量,引用指向的是同一个对象,在修改其中一个对象的时候,实际上两者都发生了改变,那么在这种情况下,如果要获得一份拷贝,那么可以用到copy模块。

    copy模块中提供了两个方法,一个是copy方法实现的是浅拷贝,一个是deepcopy方法实现的是深拷贝,具体描述如下:

    对象的浅拷贝copy.copy:生成了新对象,但是对象内部的属性和内容依然引用的是原对象,从而操作速度快,并且节省内存;

    对象的深拷贝copy.deepcopy:在拷贝容器对象的时候,递归的拷贝其内部引用的对象-包括所有的元素,属性,元素的元素和元素的属性

    >>> import copy
    >>> list1 = [[1,2,'kel'],[1,2]]
    >>> list2 = copy.copy(list1) #使用浅拷贝生成了一个新的对象,但是里面的对象依旧是原来对象的引用
    >>> print list1,list2
    [[1, 2, 'kel'], [1, 2]] [[1, 2, 'kel'], [1, 2]]
    >>> list1[0][2] = 'changed'
    >>> print list1,list2
    [[1, 2, 'changed'], [1, 2]] [[1, 2, 'changed'], [1, 2]] #从而在修改其中一个对象的时候,所有的都会发生改变
    >>> list3 =copy.deepcopy(list1)  #使用深拷贝进行拷贝所有的元素和属性
    >>> print list1,list3
    [[1, 2, 'changed'], [1, 2]] [[1, 2, 'changed'], [1, 2]]
    >>> list1[0][2]='kel'
    >>> print list1,list3
    [[1, 2, 'kel'], [1, 2]] [[1, 2, 'changed'], [1, 2]] #在使用深拷贝的时候,改变其中一个对象的子元素,其他的对象不会发生改变
    
    在进行普通的拷贝的时候,如果具有内建方法,那么可以直接使用内建的属性来进行拷贝。

    列表:l=list(L),字典:dict = dict(t),集合:s = set(s) 在使用这种方法进行拷贝的时候,方便快捷并且比较简洁。

    在提供拷贝的功能的时候,可以使用两种方式,一种是提供__copy__方法,一种是提供__getstate__方法和__setstate__方法,从而可以直接在类中使用拷贝功能。


    2、is操作符


    is操作符用来检查两个对象是否相同,而不是相等,也就是is主要比较的是引用的地址,而不是内容是否相同:

    >>> list1,list2,list3
    ([[1, 2, 'kel'], [1, 2]], [[1, 2, 'kel'], [1, 2]], [[1, 2, 'changed'], [1, 2]])
    >>> list1 is list2
    False
    >>> list1 is list3
    False
    从上面可以看到,list1和list2的内容是相同的,但是为False,而list2是由浅拷贝从而生成的新对象,从而引用是不同的,从而返回为False,而深拷贝也是生成了一个新的对象。


    3、 拷贝列表

    也可以使用其他的方法来进行拷贝,例如在序列中可以使用切片和列表解析

    L = L[:] #使用切片
    [x for x in L] #使用列表解析


    当时改变一个列表,而不是新建一个列表的时候,最好的方法是使用列表解析:

    L[:] = [lambda x : x >5 ,for x in L]
    在对原来的列表进行操作的时候,不需要重新进行绑定,只要在原来的列表中进行修改即可,从而使用的是原列表的切片方法。

    当要对每个元素调用一个函数的时候,最好是使用imap方法,从而和列表解析是差不多的,但是比列表解析更加清晰。

    生成器表达式和列表解析的语法相同,不同的在于个一个是圆括号,一个是中括号。,在生成器中,每次仅获取到一个元素。

    [x if x>0 else 0 for x in list if x >5]
    在列表解析中,条件判断放在前面,而循环放在后面,也可以在后面进行条件判断,但是放前面可以获得不同的值。


    4、查找列表中元素,如果存在返回

    def get_list(li,i,v=None):
        if -len(li) <= i <len(li):
            return li[i]
        else:
            return v
    
    list1 = [1,2,3,'kel']
    print get_list(list1,3)
    print get_list(list1,8)
    定义了一个方法,如果列表的有效索引在列表接收的长度之内,那么就会返回列表的值,如果不存在,那么返回为None

    结果如下:

    [root@python 410]# python getitem.py 
    kel
    None
    从上面可以看到,3在列表索引有效范围为-len(L)到len(L)之间,从而返回了list的值,而当不在这个范围内的时候,返回为默认值None

    5、循环访问序列中的元素和索引
    在很多时候,需要循环的索引,而在很多迭代中,并不是按照索引值来进行循环的,从而可以使用内建函数enumerate。

    循环都是用for进行循环,从而没有索引,如下:

    for item in sequence:
        process(item)

    使用enumerate内建函数后,可以得到索引值:

    >>> for index,item in enumerate([1,2,3,4]):
    ...     print index,item
    ... 
    0 1
    1 2
    2 3
    3 4

    在for的主题中,索引和值可以同时访问。





    for linux and python
  • 相关阅读:
    UITableView加载显示更多内容
    UITableView  折叠效果
    40个GitHub上最受欢迎的iOS开源项目
    oc中的block使用心得
    iOS CGRectContainsPoint的用法
    ios NSComparator 三种枚举类型
    错误提示 Unsupported compiler 'com.apple.compilers.llvmgcc42' selected for architecture 'i386'
    IOS 第三方库之-MBProgressHUD的使用详解
    ios 测试工程是否内存泄漏
    单双击手势
  • 原文地址:https://www.cnblogs.com/kellyseeme/p/5525046.html
Copyright © 2011-2022 走看看