精华内容
下载资源
问答
  • python中的列表生成式

    2020-08-15 22:31:45
    1.列表生成式 (List Comprehensions) 列表生成式:是python内置的比较简单但是功能强大的用于生成list的生成式 语法: [元素 for循环 if语句] 说明: 元素和for循环不能省略,但是,if语句可以省略 列表...

    列表生成式   (List Comprehensions)

         1.列表生成式:是python内置的比较简单但是功能强大的用于生成list的生成式

         语法:  [元素  for循环  if语句]

        说明:   元素和for循环不能省略,但是,if语句可以省略

      第一个需求:生成一个列表,[1,2,3,4,5,6,7,8,9]

       用传统的方法,就可以完成

    # 方式一:使用range()和list()函数
    list1 = list(range(1, 10))
    print(list1)
    
    # 方式二:循环,添加到列表中
    list2 = []
    for i in range(1,10):
        list2.append(i)
    print(list2)
    
    """
    通过range生成的列表,缺点:生成的列表规律性较强,其中的元素相互之间的差值是相等的【step】
    """
    

    第二个需求:  生成一个列表,[1,4,9,16,25,36,49,64,81]

    使用传统的方式
    list3 = []
    for i in range(1,10):
        list3.append(i ** 2)
    print(list3)
    
    使用列表生成式,        会发现就会代码会少很多
    list4 = [i ** 2 for i in range(1, 10) if i % 2 == 1]
    print(list4)
    

    第三个需求:生成一个列表,列表中的元素为1-100以内3的倍数

    # 方式一:传统方式
    list5 = []
    for i in range(1, 100):
        if i % 3 == 0:
            list5.append(i)
    print(list5)
    # 方式二:使用列表生成式
    list6 = [i for i in range(1, 100) if i % 3 == 0]
    print(list6)

    2.列表生成式可以书写多个for循环,表示for循环的嵌套

    # 方式一:传统方式
    list7 = []
    for i in "abc":
        for j in "xyz":
            list7.append(i + j)
    print(list7)
    # 方式二:使用列表生成式
    list8 = [i + j for i in "abc" for j in "xyz"]
    print(list8)
    

    3.在for循环中可以定义多个变量

        需求:有个字典  dict1 = {'a': 10, 'b': 20, 'c': 30}  ,  需要得到这种列表样子: ['a10', 'b20', 'c30']

    dict1 = {'a': 10, 'b': 20, 'c': 30}
    # 方式一:传统方式
    list9 = []
    for key, value in dict1.items():
        list9.append(str(key) + str(value))
    print(list9)
    # 方式二:使用列表生成式
    list10 = [key + str(value) for key, value in dict1.items()]
    print(list10)

    4.列表生成式的好处和坏处

    """
        注意:列表生成式相比较普通列表的生成式,比较简洁,
            但是只能实现简单的逻辑,否则代码的可读性降低
    """

    5.使用列表生成式将一个列表元素中的小写字母转换为大写,生成一个新的列表

    list_1 = ['hello', 10, 'Abc', 'asBd', True]
    # 方式一:
    newlist_1 = []
    for s in list_1:
        if isinstance(s, str):  # isinstance()来判断是不是str类型
            newlist_1.append(s.upper())
    print(newlist_1)
    # 方式二:
    newlist_2 = [s.upper() for s in list_1 if isinstance(s, str)]
    print(newlist_2)

     

     

    展开全文
  • 列表和元组都是数组,列表是动态的数组可以修改,元组是静态的数组不可修改。除此之外,大家还能想到其他的区别吗?接下来就让我来详细给大家介绍一下吧。 列表 为了更好的了解列表,先来看看列表存储结 ...

    前言

    相信大家对于Python的列表元组两种数据结构并不陌生了,如果我问大家这两种数据结构有什么区别呢?列表和元组都是数组,列表是动态的数组可以修改,元组是静态的数组不可修改。除此之外,大家还能想到其他的区别吗?接下来就让我来详细给大家介绍一下吧。

    列表中高效搜索算法

    • 存储结构

    为了更好的了解列表,先来看看列表存储结构,列表其实也就是数组。当我们创建列表时,系统就需要给这个列表分配一块存储空间用来存放地址,地址指向的就是列表中存放的数据
    在这里插入图片描述
    需要注意的是,如果给列表分配了8块存储空间,那么实际上列表能用的空间只有7,第一块空间是用来存放列表的长度

    查询任意指定的元素时,只需要知道列表存储的起始位置元素存储的位置(这里的位置不是指地址,而是指元素相对于起始地址的偏移量),就可以很快到查询到。因为每块存储空间占用的大小(存储地址)都是一样的,占用一个整形大小的空间用来指向列表中存放的数据,所以在查询元素的时候与列表中存放的数据类型无关。

    例如:列表的起始位置是M,我们想要列表中的第k个元素,这时候只需要将指针移到M+k的位置,然后再读取数据就好了。也就是说,只要数据保存在一个连续的存储空间中时,查询指定位置元素的时间复杂度为O(1)

    • 列表查询

    在介绍列表的存储结构的时候,已经知道了如果指定列表存储的起始位置,当需要查询指定位置元素时的时间复杂度为O(1)。那如果是已知元素的值,查询元素的位置,此时的时间复杂度又是多少呢?如果大家对这段话不是很理解,下面举例说明一下。

    例如:有一个列表a为[5,3,7,8,2,1,4],此时如果想要获取a[2]的元素值时的时间复杂度为O(1),此时查询元素值与列表的大小无关。当我们想知道4是否在列表中,最简单的方法就是遍历数组中的每一个元素与我们寻找的元素一一比对是否相等,这种方法最差的时间复杂度为O(n),也就是没有找到符合位置的元素或者元素在列表的最后一个位置,Python内置的list.index()方法正是采用的这种算法。

    面对这种情况,如果想要进一步提升算法的查询速度,有两种算法可以解决。第一种,更改数据结构,将列表改为字典,然后通过字典的键来获取值,此时也能够得到O(1)的时间复杂度,但是转换过程需要加入计算量,,而且字典的键不能重复。第二种方式就是,先对列表进行排序,然后再通过二分法查找元素是否存在列表中只需要O(log(n))的时间复杂度,但是排序还是需要引入一些计算量,这种先排序后查找算法在某些时候是最优的,当列表比较大的时候。

    Python提供了一个bisect模块,可以保证你在向列表中插入元素的时候保持排序的同时添加元素,还提供了一个高度优化过的二分查找算法,这就是Python的强大之处,第三方库非常丰富,免去了重复造轮子的麻烦。bisect模块提供的函数,可以将添加的新元素插入在列表正确的位置上,使得列表始终满足排序,以便我们能够很快的找到元素的位置。

    使用bisect模块向列表中插入元素

    import bisect,random
    random_list = []
    for i in range(10):
        #产生一个随机数
        random_value = random.randint(0,100)
        #使用bisect模块向列表中插入元素,并且保持列表排序
        bisect.insort(random_list,random_value)
    print(random_list)
    #[3, 3, 5, 51, 53, 67, 68, 90, 94, 95]
    

    使用bisect模块查询元素的位置

    import bisect,random
    
    def find_list_index(insert_list,find_value):
        """寻找列表中与find_value最接近元素的位置
        :param insert_list: 列表(由小到大排序)
        :param find_value: 寻找的元素
        :return: 列表中与寻找元素最接近的位置
        """
        #bisect_left方法返回,列表中大于或等于该元素的位置
        i = bisect.bisect_left(insert_list,find_value)
        #寻找元素大于列表中最大值,返回列表的长度
        if i == len(insert_list):
            return i - 1
        #寻找元素刚好等于列表中的这个元素
        elif insert_list[i] == find_value:
            return i
        #寻找的元素在列表中某两个值之间
        elif i > 0:
            j = i - 1
            #返回列表中与寻找元素大小最接近的位置
            if insert_list[i] - find_value > find_value - insert_list[j]:
                return j
        return i
    
    
    random_list = []
    for i in range(10):
        #产生一个随机数
        random_value = random.randint(0,100)
        #使用bisect模块向列表中插入元素,并且保持列表排序
        bisect.insort(random_list,random_value)
    
    print(random_list)
    #[0, 1, 2, 13, 35, 37, 51, 64, 72, 86]
    #查找与50最接近元素的位置
    print(find_list_index(random_list,50))
    #6
    

    列表和元组的区别

    在前面也简单介绍过了列表和元组的一些区别,这里我们做个总结:

    1. 列表动态数组,列表的长度可变,内容可修改
    2. 元组静态数组,长度不可变,内容不可修改
    3. 元组缓存在Python的运行时环境,所以在使用元组的时候不需要去通过系统的内核来分配内存

    所以,对于不会改变的数据,建议使用元组进行存储,这样在读取数据的时候能够高效。而对于需要改变的数据,则选择列表进行存储。需要注意的是,列表和元组都可以存储不同的数据类型,即保存数据的时候允许混合类型,但是这样操作的坏处就是会带来一些额外的开销

    列表

    前面也介绍过了,列表属于动态数组,所以列表的大小是可变的,当创建一个大小为N的列表时,此时列表的大小为N,那么如果我使用append方法添加一个元素时,此时列表的大小是N+1吗?

    当然不是,实际上,当第一次使用append方法时,Python会先创建一个列表,用来存放之前的N个元素以及额外添加的元素。而分配给这个列表的大小不是N+1,而是M(M>N),这样做的主要目的是为了便于以后使用append的方法添加元素时,不需要频繁的去创建列表和复制数据

    列表的超额分配发生在第一次往列表中添加元素,创建列表时,是按照所需要的大小创建的,不存在超额分配。

    列表的超额分配公式:

    M = ( N &gt; &gt; 3 ) + ( N &lt; 9 ? 3 : 6 ) M = (N &gt;&gt;3 ) + (N &lt; 9 ? 3 : 6) M=(N>>3)+(N<9?3:6)
    在这里插入图片描述
    注意:并不是每一次append的时候都会导致超额分配,第一次添加数据的时候会发生超额分配,后面再添加数据的时候,只有当N==M的时候,即列表的空间已经满了没法存储更多的数据时,才会发生超额分配。虽然说,列表超额分配的空间并不是很多,但是如果列表的数量很多时,超额分配的空间还是不容小视的

    元组

    元组是静态数组,所以当元组被创建之后其长度和内容都无法修改。虽然说,无法修改元组,但是我们可以将两个元组拼接成一个新的元组,而且不需要为新的元组分配任何额外的空间。这个操作类似于列表的append操作,唯一的区别在于当列表的内存耗尽的时候,再使用append时会开辟一些额外的内存空间,会导致部分空间的浪费。而元组是直接将两个元组相加再返回一个新的元组,这一过程不会产生额外的内存空间
    主要注意的是,在使用列表和元组保存同样的数据时,即使列表没用使用append操作,列表所需要的内存仍然是大于元组的,这是为了使得让列表能够记住更多自身的一些信息以便它们能够进行高效的resize。
    除此之外,元组还有一个好处在于,资源缓存。Python也是一门垃圾收集语言,当某些变量我们不再使用的时候,系统就会自动回收释放内存,以便其他程序或变量使用。对于长度为1-20的元组而言,即使不再使用,也不会马上释放内存,而是留给以后使用。当需要创建新的元组的时候,就可以直接使用这块内存,而不需要再去向系统申请内存

    总结:要想高效的寻找列表中的某一个元素是否存在时,可以让列表进行排序,然后再去查找。对于不会改变的数据,建议使用元组进行保存,如果需要频繁修改数据还是使用列表。

    展开全文
  • 关于及时刷新wifi列表

    2018-08-17 14:18:34
    看wifi列表能不能及时刷新出新的wifi名,直接测的结果很正常,最多五秒就能刷新出 来。可是当telnet进去后,打开wpa_cli,每隔6秒才会收到一次 “<3>CTRL-EVENT-SCAN-RESULTS”,且需要收到五次以上才能“scan_result...
  • 关于散列表的大小设定

    千次阅读 2018-11-28 18:55:07
    数据库课上老师提出的问题,大意是给一个集合S,给一个散列函数和相应的散列表,长为m,从S映射到表,问 使得给一个x,通过散列表判断其不在S中的概率小于0.05,这个m该是多少? 老师说这个问题是美国大学生都会证的...

    数据库课上老师提出的问题,大意是给一个集合S,给一个散列函数和相应的散列表,长为m,从S映射到表,问 使得给一个x,通过散列表判断其不在S中的概率小于0.05,这个m该是多少?
    老师说这个问题是美国大学生都会证的问题,这也是中国大学生研究生缺乏的思考能力。
    我完全没头绪。。只是在想这跟m有什么关系,下课后也没找到合适的资料。这里整理一下我查到的一些关于哈希表的长度设定问题的英文资料和机翻。
    想看知识点的直接翻到最后即可。

    USCD_EDU

    http://cseweb.ucsd.edu/~kube/cls/100/Lectures/lec16/lec16-8.html
    Hash table size

    • By “size” of the hash table we mean how many slots or buckets it has [ 哈希表的“大小”是指它有多少个槽或桶]

    • Choice of hash table size depends in part on choice of hash function, and collision resolution strategy [ 散列表大小的选择部分取决于散列函数的选择和冲突解决策略]

    • But a good general “rule of thumb” is: [ 但一个好的一般“经验法则”是:]
      The hash table should be an array with length about 1.3 times the maximum number of keys that will actually be in the table, and [ 哈希表应该是一个数组,其长度约为表中实际存在的最大键数的1.3倍]

    • Size of hash table array should be a prime number [ 哈希表数组的大小应该是素数]

    • So, let M = the next prime larger than 1.3 times the number of keys you will want to store in the table, and create the table as an array of length M [ 因此,让M =下一个素数大于您想要存储在表中的键数的1.3倍,并将表创建为长度为M的数组]

    • (If you underestimate the number of keys, you may have to create a larger table and rehash the entries when it gets too full; if you overestimate the number of keys, you will be wasting some space) [ (如果你低估了键的数量,你可能需要创建一个更大的表,并在条目太满时重新输入条目;如果你高估了键的数量,你将浪费一些空间)]

    How is the size of a hash table determined How should optimization be done for it to be fast?

    https://www.quora.com/How-is-the-size-of-a-hash-table-determined-How-should-optimization-be-done-for-it-to-be-fast

    • HOW

    It’s a tuning parameter - it depends what you’re trying to optimize and what resources you have or are willing to commit but thinking performance will be proportional to average collision chain length is the right thing to be managing. [ 这是一个调整参数 - 它取决于您要优化的内容以及您拥有或愿意承诺的资源,但思考性能与平均冲突链长度成正比是正确的管理方式。]

    I don’t know what your application is but assuming you optimize collision handling 3-4 chains will be blisteringly fast on any modern laptop (up). [ 我不知道您的应用程序是什么,但假设您优化了碰撞处理3-4链条在任何现代笔记本电脑上都会非常快(上)。] If you’re on a phone or smaller device you might find this is more of a size/speed trade-off. [ 如果您使用的是手机或小型设备,您可能会发现这更多的是尺寸/速度权衡。]

    It’s a common myth for this kind of hash-table that you should pick a prime number but because your hash value has a tendency to have a fixed remainder modulo 33 you should pick something co-prime with 33. [ 对于这种哈希表来说,你应该选择素数是一个常见的神话,但是因为你的哈希值有一个固定余数模33的倾向,你应该选择一个33的共同素数。]

    A smart choice is a power of 2. [ 聪明的选择是2的力量。] That’s because you can obtain the remainder by masking bits with & and avoid a (relatively) costly / implicit in your %. [ 那是因为你可以通过用&屏蔽位来获得余数,并避免在你的%中(相对)代价高昂/隐含。]

    NB: A side-effect of using powers of 2 is that it’s easy to divide or combine collision chains if you resize the table dynamically. [ 注意:使用2的幂的副作用是,如果动态调整表的大小,则很容易划分或组合碰撞链。] However I get the impression you have a static dictionary and won’t be re-sizing. [ 但是我得到的印象是你有一个静态字典,不会重新调整大小。]

    • Optimized? [ 优化?]

    First, make sure you retain the full hash (an unsigned 32-bit int will be likely suitable). [ 首先,确保保留完整的哈希值(无符号的32位int可能是合适的)。]
    Second when traversing a collision chain compare hash before value. [ 第二,当遍历碰撞链时比较值之前的散列。] If the hashes don’t match you don’t need a (relatively) expensive string comparison. [ 如果散列不匹配,则不需要(相对)昂贵的字符串比较。]
    The hash you’ve chosen is known to have good performance with English text you should find few if any collisions at full 32-bit hash comparison and make next to zero failed string comparisons. [ 您已选择的哈希已知具有良好的英文文本性能,如果在完全32位哈希比较中发生任何冲突,则应该找到很少,并且接下来的零字符串比较失败。]

    Third consider ordering the collision chain. [ 第三,考虑订购碰撞链。] If access is random order it by hash value. [ 如果访问是随机的,则按哈希值排序。]
    That way you can dive out of a chain when you realize the look-up value can’t be held. [ 这样,当您意识到无法保持查找值时,您可以跳出链条。]

    Alternatively if access isn’t random consider ordering the collision chains by a static or dynamic frequency. [ 或者,如果访问不是随机的,则考虑通过静态或动态频率对碰撞链进行排序。] Static frequency would be based on occurrence of a word in some text “corpus”. [ 静态频率将基于某些文本“语料库”中单词的出现。] That is you’d want ‘the’ to appear at the front of its collision chain and ‘wayzgoose’ likely towards the end! [ 那就是你希望’the’出现在它碰撞链的前面,并且’wayzgoose’可能会到达终点!]
    Dynamic frequency would involve moving words that are ‘hit’ to the front of their collision chain knowing words recur in a given text. [ 动态频率将涉及将“击中”的单词移动到其碰撞链的前面,知道单词在给定文本中重复出现。]

    If you are writing a spell checker (and I’ve somewhat assumed that’s the application) I really do recommend finding a corpus. [ 如果你正在写一个拼写检查器(我有点认为这是应用程序)我真的建议找一个语料库。] It doesn’t even have to be very big because (of course) the common words are common and will sort to the front very quickly and even if the ‘uncommon’ words aren’t optimized - they have less impact because they’re uncommon! [ 它甚至不必非常大,因为(当然)常见的词很常见并且会很快排在前面,即使“不常见”的词语没有被优化 - 它们的影响也很小,因为它们并不常见!]

    PS: I also know a practically perfect (in the formal sense) hash for English words however I think you’ll find your hash is pretty good. [ PS:我也知道一个几乎完美的(在正式意义上)英语单词的哈希,但我想你会发现你的哈希非常好。]

    总结

    1. 散列表的大小的选择部分取决于散列函数的选择和冲突解决的策略

    2. 其实讨论的是平衡性能与平均冲突长度平衡性能与平均冲突长度
      一般情况下,越短搜的越快越省空间,但相应冲突机会就越大(散列函数影响力更大)

    3. 处理碰撞是非常重要的一环,比散列表的大小重要多了。

    4. 经验:

    • 约为表中实际存在的最大的键值的1.3倍
    • 素数
    • 使用2的幂也是个方法,好处是可以通过直接位操作降低代价;坏处是:如果需要动态调整表的大小,很容对碰撞链进行划分或者合并。
    1. 其实最后也没解决关于概率,证明这些的原问题,不过总感觉老师说的是散列、碰撞那些的概率。。可能我没听清,当然不排除老师口误了哈哈哈。
    展开全文
  • 前言相信大家对于Python的列表和元组两种数据结构并不陌生了,如果我问大家这两种数据结构有什么区别呢?列表和元组都是数组,列表是动态的数组可以修改,元组是静态的数组不可修改。除此之外,大家还能想到其他的...

    前言

    相信大家对于Python的列表元组两种数据结构并不陌生了,如果我问大家这两种数据结构有什么区别呢?列表和元组都是数组,列表是动态的数组可以修改,元组是静态的数组不可修改。除此之外,大家还能想到其他的区别吗?接下来就让我来详细给大家介绍一下吧。

    列表中高效搜索算法

    • 存储结构

    为了更好的了解列表,先来看看列表存储结构,列表其实也就是数组。当我们创建列表时,系统就需要给这个列表分配一块存储空间用来存放地址,地址指向的就是列表中存放的数据

    ec9acc05c4af094e3afc56c6decede33.png

    数组内存结构

    需要注意的是,如果给列表分配了8块存储空间,那么实际上列表能用的空间只有7,第一块空间是用来存放列表的长度

    查询任意指定的元素时,只需要知道列表存储的起始位置元素存储的位置(这里的位置不是指地址,而是指元素相对于起始地址的偏移量),就可以很快到查询到。因为每块存储空间占用的大小(存储地址)都是一样的,占用一个整形大小的空间用来指向列表中存放的数据,所以在查询元素的时候与列表中存放的数据类型无关。

    例如:列表的起始位置是M,我们想要列表中的第k个元素,这时候只需要将指针移到M+k的位置,然后再读取数据就好了。也就是说,只要数据保存在一个连续的存储空间中时,查询指定位置元素的时间复杂度为O(1)。
    • 列表查询

    在介绍列表的存储结构的时候,已经知道了如果指定列表存储的起始位置,当需要查询指定位置元素时的时间复杂度为O(1)。那如果是已知元素的值,查询元素的位置,此时的时间复杂度又是多少呢?如果大家对这段话不是很理解,下面举例说明一下。

    例如:有一个列表a为[5,3,7,8,2,1,4],此时如果想要获取a[2]的元素值时的时间复杂度为O(1),此时查询元素值与列表的大小无关。当我们想知道4是否在列表中,最简单的方法就是遍历数组中的每一个元素与我们寻找的元素一一比对是否相等,这种方法最差的时间复杂度为O(n),也就是没有找到符合位置的元素或者元素在列表的最后一个位置,Python内置的list.index()方法正是采用的这种算法。

    面对这种情况,如果想要进一步提升算法的查询速度,有两种算法可以解决。第一种,更改数据结构将列表改为字典,然后通过字典的键来获取值,此时也能够得到O(1)的时间复杂度,但是转换过程需要加入计算量,,而且字典的键不能重复。第二种方式就是,先对列表进行排序,然后再通过二分法查找元素是否存在列表中只需要O(log(n))的时间复杂度,但是排序还是需要引入一些计算量,这种先排序后查找算法在某些时候是最优的当列表比较大的时候

    Python提供了一个bisect模块,可以保证你在向列表中插入元素的时候保持排序的同时添加元素,还提供了一个高度优化过的二分查找算法,这就是Python的强大之处,第三方库非常丰富,免去了重复造轮子的麻烦。bisect模块提供的函数,可以将添加的新元素插入在列表正确的位置上,使得列表始终满足排序,以便我们能够很快的找到元素的位置。

    使用bisect模块向列表中插入元素

    import bisect,randomrandom_list = []for i in range(10): #产生一个随机数 random_value = random.randint(0,100) #使用bisect模块向列表中插入元素,并且保持列表排序 bisect.insort(random_list,random_value)print(random_list)#[3, 3, 5, 51, 53, 67, 68, 90, 94, 95]

    bisect模块查询元素的位置

    import bisect,randomdef find_list_index(insert_list,find_value): """寻找列表中与find_value最接近元素的位置 :param insert_list: 列表(由小到大排序) :param find_value: 寻找的元素 :return: 列表中与寻找元素最接近的位置 """ #bisect_left方法返回,列表中大于或等于该元素的位置 i = bisect.bisect_left(insert_list,find_value) #寻找元素大于列表中最大值,返回列表的长度 if i == len(insert_list): return i - 1 #寻找元素刚好等于列表中的这个元素 elif insert_list[i] == find_value: return i #寻找的元素在列表中某两个值之间 elif i > 0: j = i - 1 #返回列表中与寻找元素大小最接近的位置 if insert_list[i] - find_value > find_value - insert_list[j]: return j return irandom_list = []for i in range(10): #产生一个随机数 random_value = random.randint(0,100) #使用bisect模块向列表中插入元素,并且保持列表排序 bisect.insort(random_list,random_value)print(random_list)#[0, 1, 2, 13, 35, 37, 51, 64, 72, 86]#查找与50最接近元素的位置print(find_list_index(random_list,50))#6

    列表和元组的区别

    在前面也简单介绍过了列表和元组的一些区别,这里我们做个总结:

    1. 列表是动态数组,列表的长度可变,内容可修改
    2. 元组是静态数组,长度不可变,内容不可修改
    3. 元组缓存在Python的运行时环境,所以在使用元组的时候不需要去通过系统的内核来分配内存

    所以,对于不会改变的数据,建议使用元组进行存储,这样在读取数据的时候能够高效。而对于需要改变的数据,则选择列表进行存储。需要注意的是,列表和元组都可以存储不同的数据类型,即保存数据的时候允许混合类型,但是这样操作的坏处就是会带来一些额外的开销

    列表

    前面也介绍过了,列表属于动态数组,所以列表的大小是可变的,当创建一个大小为N的列表时,此时列表的大小为N,那么如果我使用append方法添加一个元素时,此时列表的大小是N+1吗?

    当然不是,实际上,当第一次使用append方法时,Python会先创建一个列表,用来存放之前的N个元素以及额外添加的元素。而分配给这个列表的大小不是N+1,而是M(M>N),这样做的主要目的是为了便于以后使用append的方法添加元素时,不需要频繁的去创建列表和复制数据

    列表的超额分配发生在第一次往列表中添加元素,创建列表时,是按照所需要的大小创建的,不存在超额分配。

    列表的超额分配公式:

    825ce4c695430176dee08b5fbc7fc0df.png

    超额分配公式

    e3faf65c953029ec77b11e227fc3509b.png

    注意:并不是每一次append的时候都会导致超额分配,第一次添加数据的时候会发生超额分配,后面再添加数据的时候,只有当N==M的时候,即列表的空间已经满了没法存储更多的数据时,才会发生超额分配。虽然说,列表超额分配的空间并不是很多,但是如果列表的数量很多时,超额分配的空间还是不容小视的

    元组

    元组是静态数组,所以当元组被创建之后其长度和内容都无法修改。虽然说,无法修改元组,但是我们可以将两个元组拼接成一个新的元组,而且不需要为新的元组分配任何额外的空间。这个操作类似于列表的append操作,唯一的区别在于当列表的内存耗尽的时候,再使用append时会开辟一些额外的内存空间,会导致部分空间的浪费。而元组是直接将两个元组相加再返回一个新的元组,这一过程不会产生额外的内存空间。

    主要注意的是,在使用列表和元组保存同样的数据时,即使列表没用使用append操作,列表所需要的内存仍然是大于元组的,这是为了使得让列表能够记住更多自身的一些信息以便它们能够进行高效的resize。

    除此之外,元组还有一个好处在于,资源缓存。Python也是一门垃圾收集语言,当某些变量我们不再使用的时候,系统就会自动回收释放内存,以便其他程序或变量使用。对于长度为1-20的元组而言,即使不再使用,也不会马上释放内存,而是留给以后使用。当需要创建新的元组的时候,就可以直接使用这块内存,而不需要再去向系统申请内存。

    总结:要想高效的寻找列表中的某一个元素是否存在时,可以让列表进行排序,然后再去查找。对于不会改变的数据,建议使用元组进行保存,如果需要频繁修改数据还是使用列表。

    展开全文
  • Python 让列表逆序排列的 3 种方式

    万次阅读 多人点赞 2019-06-05 15:40:30
    列表逆序排列是我们编程时常碰到的问题,比如现在有一些客户的姓名是将拼音的首字母按 A - Z 排列的,而你现在想找一个姓张( Z )的客户,你就有了将姓名逆序排列的需求了。而在 Python 中,将列表逆序有 3 种...
  • 列表逆序

    2021-03-21 08:22:04
    会直接在原来的列表里面将元素进行逆序排列,不需要创建新的副本用于存储结果。 mylist=[1,2,3] mylist.reverse() mylist [3,2,1] 调用 list.reverse() 的返回值是 None ,它逆序的结果直接体现在原来的列表里面。 ...
  • Android RecyclerView 二级列表实现

    万次阅读 热门讨论 2017-04-18 15:05:24
    Android RecyclerView 二级列表实现 简述 实现基础 实现思路 实现过程 二级列表数据格式 RecyclerView Item状态 ViewHolder 其它属性和方法 getItemStatusByPosition 方法实现 getItemCount方法实现 其它方法实现 ...
  • 虚拟机维护一个列表,记录可用的内存块,分配给对象列表中一块足够大的内存空间 显然,采用何种方式要基于虚拟机堆内存是否规整,这又由采用的垃圾收集器是否带有压缩整理功能决定,所以类似Serial、ParNes等收集器时采用...
  • redis学习之列表

    2019-09-06 07:56:21
    redis 列表是简单的字符串队列,可以在列表头部与尾部推入字符串,其操作时间复杂度为常数级O(1),速度非常快。而且是按照推入的顺序排序,每个redis列表最少可以包含40亿个字符串。坏消息是访问列表里的元素效率不...
  • 在进行一个运算时发现list类型不能直接进行矩阵运算,需要用array()函数转换为数组类型,然后进行运算。但是发现结果有问题,本来是一列float,求和之后变成了一个大长串的数字,没有得到想要的结果。...
  • WordPress Ping列表集合

    2020-05-21 19:52:04
    什么是WordPress Ping列表? WordPress Ping列表用于通知... 这是我在线收集的124个WordPress Ping列表,将所有内容都添加到您的ping列表中没有什么害处。 希望对你有帮助 http://1470.net/api/ping http://...
  • :key是为vue的响应式渲染提供方法,在列表中单条数据改变的情况下,可以进行单独渲染,减少页面资源消耗。 在项目运行的时候也不会有问题发生,不过这恶心的警告让我感到无法忍受,故而研究一下:key的使用方式。 ...
  • 技术宅模块样式基本确定但是我的后台管理打算...坏处也很多。博客园地址一改变或者图片连接改变了。我的数据可能就不能加载了。。。。。不过我可以把图片下载到本地。。。暂时觉得没这个必要 博客园还是挺稳定的 ...
  • 前端面试锦集

    千次阅读 多人点赞 2019-07-20 13:41:45
    前端面试锦集
  • MySQL 面试题

    万次阅读 多人点赞 2019-09-02 16:03:33
    索引有什么坏处? 占用存储空间:索引实际上也是一张表,记录了主键与索引字段,一般以索引文件的形式存储在磁盘上。 降低更新表的速度:表的数据发生了变化,对应的索引也需要一起变更,从而减低的更新速度。...
  • 列表学习

    2019-01-31 13:55:58
    列表的内部数据结构是数组和链表的结合,好处是增删查改速度快,坏处是如果冲突过多会影响性能。 散列表的工作原理就是按照每一个元素给定的 键(key)值和散列函数决定这一个元素存放在数组的位置,下次取值时只...
  • 见vue/patch.js,在不带key的情况下,判断sameVnode时因为a.key和b.key都是undefined,对于列表渲染来说已经可以判断为相同节点然后调用patchVnode了,实际根本不会进入到答主给的else代码,也就无从谈起“带key比不...
  • 消息中间件MQ与RabbitMQ面试题(2020最新版)

    万次阅读 多人点赞 2020-03-01 11:11:21
    所以消息队列实际是一种非常复杂的架构,你引入它有很多好处,但是也得针对它带来的坏处做各种额外的技术方案和架构来规避掉,做好之后,你会发现,妈呀,系统复杂度提升了一个数量级,也许是复杂了 10 倍。...
  • 坏处:实在太占空间了,当你切换的时候还必须让另外一个列表手动选择到指定位置,否则就会出现 我翻到下一页了 怎么点了切换跑到首页去了 2. 使用一个collectionview colectionview具有的特性,可以定制item的...
  • 列表的三种使用方法

    2018-09-13 14:12:00
    1、无序列表ul第一,内部必须有子标签<li></li>第二,ul天生自带内外边距,还有一个p标签并级选择器*选择器,有好处也有坏处好处,省事。坏处,就是因为太省事了,加大了浏览器的负荷解决办法,按需选择...
  • 列表及行块转变

    2018-09-13 20:30:00
    坏处:太过方便,加大了浏览器的负荷 解决办法:按需选择 无序列表 ul 无序列表中都必须带有两个子标签<li></li> ul天生自带内外边距 还有p标签 list-style 这是样式属性 除去前面的符号 list-...
  • 构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。例如: class CExample { public: int a; float b; //构造函数初始化列表 CExample(): a(0),...
  • 列表 提到散列表,大家可能会想到常用的集合HashMap,HashTable等。 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来...
  • sequence序列对象,有顺序的:字符串 str,列表 list,tuple元组 键值对, 集合set ,字典dict(dictnartion) 数学结果对任何程序员都是必须的 class类,1整形,5.0浮点型,2+3j复数,都是对象即实例 数学计算用的...
  • Linux进程-命令行参数和环境列表
  • B.2 列表

    2018-12-27 21:03:00
    从很多方面来说,列表是最简单也最自然的集合类型。框架中包含很多实现,具有各种功能 和性能特征。一些常用的实现在哪里都可以使用,而一些较有难度的实现则有其专门的使用场景。 B.2.1 List<T>  在大多数...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,099
精华内容 6,439
关键字:

列表的坏处