迭代器

列表生成式 生成器 迭代器

孤人 提交于 2019-12-01 02:22:28
列表生成式 什么是列表生成式,我们先举个栗子: a = [1,2,3,4,5] 上面的语句创建一个列表,列表也可以通过下面的方法创建 a = [i*2 for i in range(10)] print(a) [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 第二种方法比第一种方法更加灵活。第二种方法就叫做列表生成式。 但是不管用哪种方法,列表中的元素都都是在列表创建的同时就被放在列表中了,如果有一个100万个数据的列表,就算我们只用第一个数据,后面的所有数据也会占用空间,造成空间浪费。有没有什么方法避免这种情况发生呢,答案是肯定的。方法就是生成器。 生成器就是把列表生成式的[ ]换成( ) a = (i*2 for i in range(10)) print(a) <generator object <genexpr> at 0x0000018B2FC65BC8> 现在a 就是一个生成器 我们现在要获取a中的数据 a = (i*2 for i in range(10)) print(a[0]) File "D:/7_Python/S14/Day4/生成器.py", line 3, in <module> print(a[0]) TypeError: 'generator' object is not subscriptable 我勒个去,报错了,没法获得数据

SGI-STL简记(八)-哈希关联容器(hash、hash_set、hash_map、hash_multiset、hash_multimap)

て烟熏妆下的殇ゞ 提交于 2019-12-01 02:04:48
stl_hash_fun.h : hash:模板函数对象类类型,一般作为hash_set、hash_map、hash_multiset、hash_multimap容器的默认哈希函数,目前提供了多个特化版本,并重载实现operator(),参数类型有char、unsigned char、char*、int等 内置可转化为整型的数据类型的版本;除const char*和char*使用了__stl_hash_string计算哈希值,其余的则直接返回参数value值作为哈希值;哈希值返回值类型为size_t; __stl_hash_string:遍历各个字符串元素,累积遍历计算哈希值,计算方式为h=0;h=5*h+*s,*s为遍历字符串相应元素,h即为最后的哈希值,类型为unsigned long; 对于其他的hash模板实例实现,如basic_string<_CharT,_Traits,_Alloc>、crope、wrope或者是用户自定义的hash模板函数对象实现; stl_hashtable.h : _Hashtable_node:哈希表节点模板类; 数据成员: _M_next:指向下一个哈希表节点的指针; _M_val:保存当前哈希表节点的值(哈希值); _Hashtable_iterator/_Hashtable_const_iterator:哈希表迭代器模板类,模板参数_Val

SGI-STL简记(七)-关联容器(set、map、multiset、multimap)

偶尔善良 提交于 2019-12-01 02:04:46
stl_set.h : set:有序关联容器,值类型和键类型为同一个,且各个容器元素唯一,插入或删除在线性时间内完成,此外插入等操作不会影响迭代器失效的情况; set:关联容器set模板类,其参数分别为_Key、_Compare、_Alloc,对应键值类型、比较函数、内存分配器; 此外提供了特化版本,其比较函数使用的是less<_Key>,分配器使用宏__STL_DEFAULT_ALLOCATOR作为默认分配器;可通过调整宏设置,故而可使用allocator< T >或alloc(malloc_alloc(即__malloc_alloc_template<0>) 或__default_alloc_template<__NODE_ALLOCATOR_THREADS, 0>)作为默认的内存分配器; 内部底层使用一个数据成员_M_t,其类型为RB_Tree红黑树结构来实现set,RB_Tree不仅被用于set,还被用于map、multiset、multimap的底层实现; set内部重声明类型key_type、value_type、key_compare、value_compare,其中key_type、value_type相同均为_Key,key_compare、value_compare则均为_Compare; 此外还有其他如指针、迭代器、引用、以及其他常规的声明类型;

SGI-STL简记(六)-序列容器(bit_vector)

人盡茶涼 提交于 2019-12-01 02:03:58
stl_bvector.h : bit_vector 重声明为vector<bool, alloc>即使用alloc作为内存分配器,其为非模板类,__BVECTOR也即vector<bool, _Alloc>为模板类,若使bit_vector重声明为__BVECTOR则也可为模板类; 相比vector,其可保持一个位一个元素而不是至少一个字节一个元素;此外基本的函数和vector相同,还有其他额外的提供的接口实现; bit_vector一般被认为是非模板类; _Bit_reference:位引用类,作为位迭代器类和bit_vector类中的引用类型; 数据成员,均为unsigned int类型或指针类型(后面为了便于分析,暂且定为4字节大小): _M_p:指向缓冲区中存储该位码值所在的地址; _M_mask:当前位掩码值(事实上目前一般情况下该值始终为仅含一个1其余均为0的二进制形式下的值),也即_M_p所指向的4字节位码中相应掩码值中为1的位置即为当前引用类表示的位值; 成员函数: 构造函数初始化位码值地址和掩码值; operator bool:重载bool转换,内部实现为将位码值和掩码值按照位取与的结果; operator=:重载赋值拷贝运算符,内部实现为为拷贝参数值为true,则调整位码值为当前位码值与掩码值按位或的结果,否则为当前位码值与掩码值取反后再与其求与的结果;

SGI-STL简记(六)-序列容器(deque)

元气小坏坏 提交于 2019-12-01 02:03:58
stl_deque.h : deque:一种具有双端插入和删除,可随机访问元素的容器,从首部或后插入或删除在常量时间内完成,从中间则需线性时间内完成; __deque_buf_size:获取队列节点缓冲区大小(工具函数),当数据元素类型字节size小于512时则为512/size,否则为1,(意味着节点容器上限为512字节或者是一个自定义类型元素大小的字节); _Deque_iterator:专用于deque容器的迭代器模板类;重声明常规类型以及迭代器类型和常量迭代器类型,迭代器分类为random_access_iterator_tag;此外声明了一个_Map_pointer指向数据元素的指针的指针; 数据成员: _M_cur:指向当前node节点容器元素的当前指针; _M_first:指向当前的node节点容器第一个元素的指针; _M_last:指向当前的node节点容器最后一个元素尾部的指针; _M_node:指向node节点容器指针的指针(其值为对应的map缓冲区的槽, 而槽的值即为对应node节点缓冲区首地址); 成员函数: _S_buffer_size:静态函数,获取当前元素类型下的节点容器缓冲区大小(内部调用__deque_buf_size),如int时,则获得大小为512/4(即128个元素); 无参构造函数初始化所有成员为空,带参构造函数T*x, _Map

SGI-STL简记(六)-序列容器(list)

女生的网名这么多〃 提交于 2019-12-01 02:03:50
stl_list.h : list:一个可从任意位置快速插入和删除元素的双向链表,可在常数时间内完成,但是取数据、查找等则需要线性时间; _List_node_base:链表节点基类struct,仅包含_M_next、_M_prev成员,其分别为指向当前节点基类类型的下一个、上一个节点的指针; _List_node:节点模板类,继承于_List_node_base,只是增加了一个数据成员_M_data,用以保存实际的node节点数据; _List_iterator_base:链表迭代器基类,所属迭代器类型为bidirectional_iterator_tag; 内部成员_M_node为当前迭代器指向的节点; _List_node_base构造函数参数类型_List_node_base,该值以初始化_M_node; _M_incr:调整当前迭代器所指的节点为该节点的下一个节点; _M_decr:调整当前迭代器所指的节点为该节点的上一个节点; 此外重载的operator==,operator!=比较操作符,其实际上是直接比较迭代器的_M_node成员(地址); _List_iterator:链表迭代器模板类,继承于_List_iterator_base; 该模板类重声明了多个常规类型;多个重载版本的构造函数以初始化迭代器; 此外重载了解引用、取指针操作符(返回为当前迭代器_M_node

SGI-STL简记(六)-序列容器(slist)

百般思念 提交于 2019-12-01 02:03:39
stl_slist.h : slist:单链表模板容器,; _Slist_node_base:单链表基类,只一个指向_Slist_node_base类型的_M_next成员指针,以表示指向下一个node节点; 一些辅助工具函数: __slist_make_link:在指定节点prev_node后插入new_node节点,以加入构成链表; __slist_previous:找到指定节点的前一个节点(需要从节点head开始遍历查找节点链表); __slist_splice_after:节点后拼接函数,两个重载版本; 一种是将__before_first节点以后的节点至__before_last节点(含)拼接插入到pos指定的节点链表后的链表中; 另一种是将给予一个__head链表头,将整个链表拼接插入到指定pos节点链表后的链表中;__slist_previous(head,0)表示获取尾节点; __slist_reverse:链表节点翻转;需要知道3个连续的节点标识便可实现翻转,然后依次遍历整个链表节点; __slist_size:遍历链表统计链表长度; _Slist_node:单链表节点模板类,继承于_Slist_node_base,只是增加了数据成员_M_data; _Slist_iterator_base:单链表迭代器基类;只是重声明了size_type、difference

SGI-STL简记(六)-序列容器(vector)

强颜欢笑 提交于 2019-12-01 02:03:37
stl_vector.h : vector:可随机访问元素的序列容器,从后插入或删除在常量时间内完成,从首部或中间则需线性时间内完成; _Vector_alloc_base:vector分配基类模板;模板参数分别为数据类型T,分配器类型_Allocator,以及一个bool标识_IsStatic(用于区分是否为标准分配器或SGI分配器); 数据成员: _M_data_allocator:分配器对象; _M_start:保存申请的缓冲区首地址(等同于容器元素的首地址); _M_finish:保存容器内容长度时的尾地址; _M_end_of_storage:保存申请的缓冲区尾地址; 成员函数: 构造函数:分配器引用allocator_type类型以初始化_M_data_allocator; get_allocator:获取分配器对象_M_data_allocator; _M_allocate:通过分配器对象_M_data_allocator分配大小为n个的元素类型大小内存空间; _M_deallocate:释放指定数据元素类型指针地址大小为n个数据元素类型大小的内存空间; 此外还提供特化版本_Vector_alloc_base<_Tp, _Allocator, true>,该分配模板基类内部不再使用分配器对象,而是直接使用simple_alloc的静态成员函数进行分配管理;

SGI-STL简记(四)-迭代器解析

大兔子大兔子 提交于 2019-12-01 02:02:52
stl_iterator_base.h : 迭代器类型萃取、特性; 几个特别的迭代器标签tag:input_iterator_tag、output_iterator_tag、forward_iterator_tag、bidirectional_iterator_tag、random_access_iterator_tag; 其中除了output_iterator_tag独立以外,其他标签tag依次为继承关系(如forward_iterator_tag继承于input_iterator_tag、....),也就意味着前者迭代器类型也可 使用后者;迭代器标签tag类型于__true_type、__false_type; 早期用于HP的input_iterator、output_iterator、forward_iterator、bidirectional_iterator、random_access_iterator分别重声明了iterator_category、value_type、 difference_type、pointer、reference类型,各迭代器的iterator_category(迭代器类别)类型使用了各自的迭代器标签tag, 此外output_iterator比较特别,其他值均为void; iterator:迭代器模板类,只是对迭代器类型重声明

通俗易懂设计模式解析——迭代器模式

不想你离开。 提交于 2019-12-01 01:28:40
前言   今天我们一起看看行为模式中的迭代器模式,迭代是重复反馈过程的活动,其目的通常是为了接近并到达所需的目标或结果。在系统开发中简单说可以理解成遍历。这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层或者内部表示。 迭代器模式介绍 一、 来由   在系统开发中,集合对象内部表示各不相同。底层构造也尽不相同。对于这些对象,我们希望在不暴露其底层和内部表示的同时,可以使外部客户访问其中元素。迭代器模式就为这一需求提供了极其优雅的实现。 二、 意图   提供一种方法顺序访问一个聚合对象中各个元素 , 而又无须暴露该对象的内部表示。 三、 案例图 四、 迭代器模式代码示例 我们从上面的案例图可见,迭代器模式主要包含以下四个部分: 抽象迭代器: 定义了访问和遍历元素的接口,然后在其子类中实现这些方法。 具体迭代器: 实现抽象迭代器接口,完成对集合对象的遍历。同时对遍历时的位置进行跟踪。 抽象聚合类: 主要用于储存对象,创建相应的迭代器对象的接口。带有一个 createIterator() 方法用于创建迭代器对象。 具体聚合类: 实现创建相应的迭代器对象的接口,实现 createIterator() 方法,并且返回与该具体聚合相对应的具体迭代器 ConcreteIterator 实例。 介绍完迭代器模式之后,接下来我们具体来看看迭代器模式的具体实现吧。具体如下: