零基础搭建量化投资系统:以Python为工具
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.6 集合及相关操作

1.创建集合

集合(set)是一个无序的不重复元素序列,集合元素也称为集合成员。集合中的元素没有重复,且没有顺序,也没有下标。

我们可以使用大括号“{}”或者set()函数创建集合。注意:因为“{}”可用来创建一个空字典,因此创建一个空集合必须用set()函数,不能用“{}”。

创建集合格式:

        var= set(x)

如果不提供任何参数,则默认会生成空集合。如果提供一个参数x,则该参数x必须是可迭代的,即一个序列,或迭代器,或支持迭代的一个对象。例如,一个列表或一个字典。

见示例3-52。

        a=set('alacazam')
        print('a= ', a)

程序运行结果:

        a=  {'m', 'l', 'a', 'z', 'c'}

类似于列表推导式,同样,集合也支持集合推导式。见示例3-53。

        b = {x for x in 'abracadabra' if x not in 'abc'}
        print('b= ', b)

程序运行结果:

        b=  {'r', 'd'}

2.增加集合元素

增加单个集合元素可以使用add(x)方法,其中参数x是一个元素值。

格式:

        sets.add(x)

sets表示一个字典。在上述操作中,如果元素已存在,则不进行任何操作。

添加多个集合元素可以使用update(x)方法,其中参数x可以是集合、列表、元组、字典等。

格式:

        sets.update(x)

见示例3-54。

        a=set('alacazam')
        print('a= ', a)
        a.add(10)
        a.add(20)
        print('a= ', a)
        a.update({'x', 'r', 'z'})
        print('a= ', a)

程序运行结果:

        a=  {'m', 'l', 'a', 'z', 'c'}
        a=  {'m', 'l', 10, 'a', 'z', 20, 'c'}
        a=  {'r', 'm', 'l', 10, 'a', 'x', 'z', 20, 'c'}

3.删除集合元素

删除集合元素可以使用remove(x)方法,其中x是一个元素值。

格式:

        sets.remove(x)

将元素x从集合sets中删除,如果元素不存在,则会发生错误。

此外,还有一个方法也能移除集合中的元素,且如果元素不存在,也不会发生错误。

格式:

        sets.discard(x)

因为集合中的元素没有顺序,所以也可以用pop()函数随机删除集合中的一个元素。一般会删除显示顺序的第一个元素,并返回删除掉的元素值。

格式:

        var=sets.pop()

见示例3-55。

        #删除集合元素
        b={1,2,3,5}
        b.discard(2)
        print(’删除b中元素2: ', b)
        b.discard(2)
        print(’删除b中元素2(没有报错): ', b)
        b.remove(3)
        print(’删除b中元素3: ', b)
        #弹出一个集合元素
        d=b.pop()
        print(’弹出一个集合元素:', d, ' b= ', b)

程序运行结果:

        删除b中元素2:  {1, 3, 5}
        删除b中元素2(没有报错):  {1, 3, 5}
        删除b中元素3:  {1, 5}
        弹出一个集合元素: 1  b=  {5}

4.集合复制

集合是对象数据,而对象数据不能通过变量来直接赋值。例如,假设b是集合,e=b,则id(e)和id(b)的地址相同。如果修改集合e,则集合b的数据也随之发生变化,因为集合e和集合b是同一份数据。

集合复制要用copy()方法。

格式:

        var=sets.copy()

此时,集合var和集合sets的地址不同,即id(var)和id(sets)不相同。此时如果修改集合var,则集合sets的数据不会发生变化,因为集合var和集合sets是不同的数据。

见示例3-56。

        a=set('alacazam')
        b=a
        c=a.copy()
        b.add(999)
        print('a= ', a)
        print('c= ', c)

程序运行结果:

        a=  {999, 'm', 'l', 'a', 'z', 'c'}
        c=  {'z', 'm', 'l', 'c', 'a'}

5.不可变集合

有时为了防止程序意外修改集合数据,可以使用冰冻函数即使用frozenset()函数返回一个不可变的集合备份。我们只能访问,不能修改不可变的集合中的元素。set()函数和frozenset()函数可以分别用来生成可变的集合和不可变的集合。

格式:

        var= frozenset(x)

如果想解冻集合就可以使用集合的set()函数。见示例3-57。

        bb = {x for x in range(1,5)}
        var = frozenset(bb)
        print(var, type(var))
        var2 = set(var)
        print(var2, type(var2))

程序运行结果:

        frozenset({1, 2, 3, 4})<class 'frozenset'>
        {1, 2, 3, 4} <class 'set'>

6.集合元素个数

格式:

        var=len(sets)

返回集合sets元素的个数。

见示例3-58。

        bb = {x for x in range(1,5)}
        print('bb= ', bb)
        print('len(bb)=', len(bb))

程序运行结果:

        bb=  {1, 2, 3, 4}
        len(bb)= 4

7.清空集合

格式:

        sets.clear()

相关演示见示例3-59。

    """
    集合
    """
    bb = {x for x in range(1,5)}
    var = frozenset(bb)
    print(var, type(var))
        var2 = set(var)
        print(var2, type(var2))
        print()
        #可以使用大括号{ }或者set()函数创建集合
        a=set('alacazam')
        print('a= ', a)
        #集合支持集合推导式
        b = {x for x in 'abracadabra' if x not in 'abc'}
        print('b= ', b)
        #增加单个集合元素用app(x)函数,其中参数x是一个元素值
        b.add('abc')
        print(’增加abc :b= ', b)
        #添加多个集合元素用update(x)函数,其中参数x可以是集合、列表、元组、字典等
        c={1,2,3}
        b.update(c)
        print(’增加c={1,2,3} :b= ', b)
        #删除集合元素
        b.discard(2)
        print(’删除b中元素2: ', b)
        b.discard(2)
        print(’删除b中元素2(没有报错): ', b)
        b.remove(3)
        print(’删除b中元素3: ', b)
        #弹出一个集合元素
        d=b.pop()
        print(’弹出一个集合元素:', d, ' b= ', b)
        #集合复制
        e=b   #把b的地址复制给了e
        e.add('xyz')
        print('e=b  e.add(\'xyz\') b= ', b)
        print('id(b)=', id(b), 'id(e)=', id(e), ' 地址相同’)
        f=b.copy()
        print('f=d.copy() f= ', f)
        print('id(b)=', id(b), 'id(f)=', id(f), ' 地址不相同’)

       #清空集合
        b.clear()
        print(’清空集合b= ', b)

程序运行结果:

        a=  {'a', 'l', 'm', 'c', 'z'}
        b=  {'r', 'd'}
        增加abc :b=  {'r', 'd', 'abc'}
        增加c={1,2,3} :b=  {1, 'd', 2, 3, 'abc', 'r'}
        删除b中元素2:  {1, 'd', 3, 'abc', 'r'}
        删除b中元素2(没有报错):  {1, 'd', 3, 'abc', 'r'}
        删除b中元素3:  {1, 'd', 'abc', 'r'}
        弹出一个集合元素: 1  b=  {'d', 'abc', 'r'}
        e=b  e.add('xyz') b=  {'d', 'abc', 'r', 'xyz'}
        id(b)= 42507400 id(e)= 42507400  地址相同
        f=d.copy() f=  {'r', 'd', 'xyz', 'abc'}
        id(b)= 42507400 id(f)= 156994024  地址不相同
        清空集合b=  set()

8.集合的相关操作

集合的基本功能包括关系测试和消除重复元素。集合对象还支持联合“union”、交集“intersection”、差集“difference”和对称差集“sysmmetric difference”等数学运算。

集合支持x in set, len(set)和for x in set等操作,这些操作同列表一样。作为一个无序的集合,其不记录元素的位置和插入点,因此,集合不支持索引下标等类似于列表的操作。

obj in s成员测试:如果obj是s中的一个元素则返回Ture,否则返回False。

obj not in s非成员测试:如果obj不是s中的一个元素则返回Ture,否则返回False。

t == s集合等价测试:测试集合s和集合t是否有相同的元素,如果有则返回Ture,否则返回False。

t ! = s集合不等价测试:与等价测试相反。

集合t和集合s支持一系列标准操作,包括并集、交集、差集和对称差集。例如:

        a = t | s   #t和s的并集
        b = t & s   #t和s的交集
        c = t - s  #求差集(项在t中,但不在s中)
        d = t ^ s   #对称差集(项在t或s中,但不会同时出现在二者中)

9.集合相关函数和方法

集合相关函数和方法的种类及功能见表3-23。

表3-23 集合相关函数和方法

10.集合和列表转换

用set()函数可以把列表转换为集合,格式如下。

        sets=set(lists)

用list()函数可以把集合转换为列表,格式如下。

        lists=list(sets)

利用集合的无重复特性,我们可以将股票代码转化为集合,并能快速完成股票代码去重、股票代码池的合并、剔除股票黑名单等运算。见示例3-60。

        #建立集合st1, st2
        st1=set(['002027', '600061', '600080', '600659'])
        print('st1= ', st1)
        st2=set(['000001', '600061', '600088', '000002'])
        print('st2= ', st2)
        #集合中增加元素
        print('\n----st1---- st1中增加600090')
        st1.add('600090')
        print(st1)
        print('\n----a = st1 | st2-----')
        #集合运算
        a = st1 | st2       #st1和st2的并集
        print(a)
        print('\n----b = st1 & st2-----')
        b = st1 & st2

#st1和st2的交集

        print(b)
        print('\n----c = st1- st2-----')
        c = st1- st2       #求差集(项在st1中,但不在st2中)
        print(c)
        print('\n----d = st1 ^ st2-----')
        d = st1 ^ st2       #对称差集(项在st1或st2中,但不会同时出现在二者中)
        print(d)
        print('\n----st2 remove 600088-----')
        #集合元素删除
        st2.discard('600088')
        print('st2 = ', st2)
        print('\n----集合转列表-----')
        st3=list(st2)
        print('st3 = ', st3)
        print('st2: ', type(st2), ' st3: ', type(st3))

程序运行结果:

        st1=  {'600080', '002027', '600659', '600061'}
        st2=  {'600088', '000001', '000002', '600061'}
        ----st1---- st1中增加600090
        {'600659', '600061', '600080', '002027', '600090'}
        ----a = st1 | st2-----
        {'600659', '600061', '600088', '000001', '600080', '002027', '600090',
    '000002'}
        ----b = st1 & st2-----
        {'600061'}
        ----c = st1- st2-----
        {'600080', '002027', '600659', '600090'}

       ----d = st1 ^ st2-----
        {'600659', '600088', '000001', '600080', '002027', '600090', '000002'}
        ----st2 remove 600088-----
        st2 =  {'000001', '000002', '600061'}
        ----集合转列表-----
        st3 =  ['000001', '000002', '600061']
        st2:  <class 'set'>  st3:  <class 'list'>