zoukankan      html  css  js  c++  java
  • Python 核心技术与实战 --01 列表与元祖

    2019-12-21

    本文章主要讲述Python的列表元组

    高级内容:

    列表与元组存储方式的差异

    了解 dir() 函数的概念:

       dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。

    l = [1,3,3,4,8]
    print(dir(l))
    
    
    ['__add__', '__class__', '__contains__',  

    '__delattr__', '__delitem__', '__dir__',

    '__doc__', '__eq__', '__format__', '__ge__',

    '__getattribute__', '__getitem__', '__gt__',

    '__hash__', '__iadd__', '__imul__', '__init__',

    '__init_subclass__', '__iter__', '__le__',

    '__len__', '__lt__', '__mul__', '__ne__',

    '__new__', '__reduce__', '__reduce_ex__',

    '__repr__', '__reversed__', '__rmul__',

    '__setattr__', '__setitem__', '__sizeof__',

    '__str__', '__subclasshook__', 'append', 'clear',

    'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
    #list 的详细内容
    
    l = [1,2,3]
    print(l.__sizeof__())
    
    
    64

    tup =(1,2,3)
    print(tup.__sizeof__())

    48

    列表和元组内的元素相同,但是 元组比列表少了 16 个字节, 为什么呢?

    由于列表是动态的,所以它需要存储指针,来指向对应的元素(上述例子中,对于int类型,8个字节)。另外由于列表可变,所以需要额外存储已经分配的长度大小(8字节),这样才能实时追踪列表空间的使用情况,当空间不足时,及时分配额外空间。

    可以看一下 python list  C 源码:

          https://blog.csdn.net/qq_33339479/article/details/81807096

    #define PyObject_VAR_HEAD      PyVarObject ob_base;
    #define Py_INVALID_SIZE (Py_ssize_t)-1
    
    /* Nothing is actually declared to be a PyObject, but every pointer to
     * a Python object can be cast to a PyObject*.  This is inheritance built
     * by hand.  Similarly every pointer to a variable-size Python object can,
     * in addition, be cast to PyVarObject*.
     */
    typedef struct _object {
        _PyObject_HEAD_EXTRA
        Py_ssize_t ob_refcnt;                                       // 引用计数值
        struct _typeobject *ob_type;                                // 基本的类型 type
    } PyObject;
    
    typedef struct {
        PyObject ob_base;                                           // 对象基本信息
        Py_ssize_t ob_size; /* Number of items in variable part */  // 变长对象的元素个数
    } PyVarObject;
    ...
    typedef struct {
        PyObject_VAR_HEAD                                           // 变量头部信息
        /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
        PyObject **ob_item;                                         // 元素指向具体指
    
        /* ob_item contains space for 'allocated' elements.  The number
         * currently in use is ob_size.
         * Invariants:
         *     0 <= ob_size <= allocated
         *     len(list) == ob_size
         *     ob_item == NULL implies ob_size == allocated == 0
         * list.sort() temporarily sets allocated to -1 to detect mutations.
         *
         * Items must normally not be NULL, except during construction when
         * the list is not yet visible outside the function that builds it.
         */
        Py_ssize_t allocated;                                       // 当前空间
    } PyListObject;
    l = []
    print(l.__sizeof__())
    
    l.append(1)
    print(l.__sizeof__())
    
    l.append(2)
    print(l.__sizeof__())
    
    
    
    40 
    72
    72

    列表的空间分配的过程可以看到,为了减小每次增加/删除的开销,python每次分配空间的时候都会多分配一点,这样的机制保证了其操作的高效性:增加/删除的时间复杂度均为O(1)

    因为元组是静态的所以Python对于小量的静态内存就会放到缓存里面,下次分配同样多的元组时,就不用向操作系统发出请求了,就直接分配之前的缓存的内存空间。这样程序的运行速度就得到保证

    初始化过程 python 3.7.0  列表优于元组(少量数据的时候)
    
    C:Usersqf>python -m timeit 'x=(1,2,3,4,5,6)'
    20000000 loops, best of 5: 12.5 nsec per loop
    
    C:Usersqf>python -m timeit 'x=[1,2,3,4,5,6]'(少量数据的时候)
    20000000 loops, best of 5: 12.2 nsec per loop
    python 3.7.0   索引操作 列表 优于元组了
    :Usersqf>python -m timeit -s 'x=[1,2,3,4,5,6]'
    0000000 loops, best of 5: 12.2 nsec per loop
    
    :Usersqf>python -m timeit -s 'x=(1,2,3,4,5,6)'
    0000000 loops, best of 5: 13.7 nsec per loop

    列表和元组的使用场景

    1. 如果存储的数据和数量不变,比如你有一个函数,需要返回的是一个地点的经纬度,然后直接传给前端渲染,那么肯定选用元组更合适。

    2.如果存储的数据或数量是可变的,比如社交平台上的一个日志功能,是统计一个用户在一周之内看了哪些用户的帖子,那么则用列表更合适

    以下为基础内容:

    1. 列表与元组基础

             共同点: 列表和元组都是一个可以放置任意数据类型的有序集合。

             不同点:1. 列表 是动态的,长度大小不固定,可以随意增加/删除 改变元素(mutable)

                               元组是静态的,长度大小固定,无法增加删减或者改变(immutable)

    例子1:

    1 # 列表的例子
    2 l = [1, 2, 3, 4]
    3 l[0] = 2
    4 print(l)
    [2, 2, 3, 4]

    1 # 元组的例子
    2 tup = (1, 2, 3, 4)
    3 tup[0] = 2
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-4-77cf1f9285bd> in <module>
          1 # 元组的例子
          2 tup = (1, 2, 3, 4)
    ----> 3 tup[0] = 2
          4 
    
    TypeError: 'tuple' object does not support item assignment

    但是你想对已有的元组做修改该怎么办呢?

    答案:开辟一块新的内存,创建新的元组

    # 元组和列表增加的例子
    tup = (1, 2, 3, 4)
    new_tup = tup + (5,)
    print(new_tup)
    
    l = [1,2,3,4]
    l.append(5)
    print(l)

    执行结果: (
    1, 2, 3, 4, 5) [1, 2, 3, 4, 5]

    2.列表和元组的索引

    python 的列表和元组都支持负索引切片

    列表和 元组支持任意嵌套

    l = [[1,2,3],[4,5,6]]
    tup =((1,2,3),(4,5,6))

    通过 list() 和 tuple() 可以将两者相互转换.

    3. 列表和元组常用的内置函数

    (1) count()

    # 元组和列表增加的例子
    tup = (1, 2, 3, 4)
    new_tup = tup + (5,)
    print(new_tup.count(1))
    
    l = [1,2,3,4]
    l.append(5)
    print(l.count(1))
    
    执行结果
    1
    1

    (2) index(item) 给出第一次出现的item 的索引

    (3) list.reverse() 原地倒转列表 (元组没有)

    l = [1,3,3,4,8]
    l.append(5)
    l.reverse()
    print(l)
    
    
    
    [5, 8, 4, 3, 3, 1]

    (4) list.sort() 排序列表 (元组没有)

    l = [1,3,3,4,8]
    l.append(5)
    l.reverse()
    l.sort()
    print(l)
    
    
    [1, 3, 3, 4, 5, 8]

    (5)reserved() 翻转后返回一个新的列表或元组

    (6) sorted()排序后返回一个新的列表或元组

  • 相关阅读:
    2. Add Two Numbers
    1. Two Sum
    22. Generate Parentheses (backTracking)
    21. Merge Two Sorted Lists
    20. Valid Parentheses (Stack)
    19. Remove Nth Node From End of List
    18. 4Sum (通用算法 nSum)
    17. Letter Combinations of a Phone Number (backtracking)
    LeetCode SQL: Combine Two Tables
    LeetCode SQL:Employees Earning More Than Their Managers
  • 原文地址:https://www.cnblogs.com/qifei-liu/p/12076976.html
Copyright © 2011-2022 走看看