Python笔记:集合

集合(set)属于Python无序可变序列,使用一对大括号作为定界符,元素之间使用逗号分隔,同一个集合内的每个元素都是唯一的,元素之间不允许重复
集合中只能包含数字、字符串、元组等不可变类型(或者说可哈希)的数据,而不能包含列表、字典、集合等可变类型的数据。

集合对象的创建与删除

直接将集合赋值给变量即可创建一个集合对象。

>>> a = {3, 5}                         #创建集合对象

使用函数set()函数将列表、元组、字符串、range对象等其他可迭代对象转换为集合,如果原来的数据中存在重复元素,则在转换为集合的时候只保留一个;如果原序列或迭代对象中有不可哈希的值无法转换成为集合,抛出异常。

>>> a_set = set(range(8, 14))                     #把range对象转换为集合
>>> a_set
{8, 9, 10, 11, 12, 13}
>>> b_set = set([0, 1, 2, 3, 0, 1, 2, 3, 7, 8])   #转换时自动去掉重复元素
>>> b_set
{0, 1, 2, 3, 7, 8}
>>> x = set()            

集合操作与运算

 (1)集合元素增加与删除

add()方法可以增加新元素,如果该元素已存在则忽略该操作,不会抛出异常;
update()方法用于合并另外一个集合中的元素到当前集合中,并自动去除重复元素。

>>> s = {1, 2, 3}
>>> s.add(3)                          #添加元素,重复元素自动忽略
>>> s
{1, 2, 3}
>>> s.update({3,4})                   #更新当前字典,自动忽略重复的元素
>>> s
{1, 2, 3, 4}

pop()方法用于随机删除并返回集合中的一个元素,如果集合为空则抛出异常;
remove()方法用于删除集合中的元素,如果指定元素不存在则抛出异常;
discard()用于从集合中删除一个特定元素,如果元素不在集合中则忽略该操作;
clear()方法清空集合删除所有元素。

>>> s.discard(5)                     #删除元素,不存在则忽略该操作
>>> s
{1, 2, 3, 4}
>>> s.remove(5)                      #删除元素,不存在就抛出异常
KeyError: 5
>>> s.pop()                          #删除并返回一个元素
1

(2)集合运算

>>> a_set = set([8, 9, 10, 11, 12, 13])
>>> b_set = {0, 1, 2, 3, 7, 8}
>>> a_set | b_set                     #并集
{0, 1, 2, 3, 7, 8, 9, 10, 11, 12, 13}
>>> a_set.union(b_set)                #并集
{0, 1, 2, 3, 7, 8, 9, 10, 11, 12, 13}
>>> a_set & b_set                     #交集
{8}
>>> a_set.intersection(b_set)         #交集
{8}
>>> a_set.difference(b_set)           #差集
{9, 10, 11, 12, 13}
>>> a_set - b_set
{9, 10, 11, 12, 13}
>>> a_set.symmetric_difference(b_set) #对称差集:去掉中间重叠部分
{0, 1, 2, 3, 7, 9, 10, 11, 12, 13}
>>> a_set ^ b_set
{0, 1, 2, 3, 7, 9, 10, 11, 12, 13}
>>> x = {1, 2, 3}
>>> y = {1, 2, 5}
>>> z = {1, 2, 3, 4}
>>> x < y                             #比较集合大小/包含关系
False
>>> x < z                             #真子集
True
>>> y < z
False
>>> {1, 2, 3} <= {1, 2, 3}            #子集
True

集合应用案例(4个)

例1 使用集合快速提取序列中单一元素,即提取出序列中所有不重复元素。如果使用传统方式的话,需要编写下面的代码:

>>> import random
#生成100个介于0到9999之间的随机数
>>> listRandom = [random.choice(range(10000)) for i in range(100)] 
>>> newSet = set(listRandom)
>>> print(newSet)

例2 返回指定范围内一定数量的不重复数字。

import random

def randomNumbers(number, start, end):
    '''使用集合来生成number个介于start和end之间的不重复随机数'''
    data = set()
    while len(data)<number:
        element = random.randint(start, end)
        data.add(element)
    return data

data = randomNumbers(10, 1, 100)
print(data)

例3 测试指定列表中是否包含非法数据。

import random

lstColor = ('red', 'green', 'blue')
colors = [random.choice(lstColor) for i in range(10000)]

for item in colors:                    #遍历列表中的元素并逐个判断
    if item not in lstColor:
        print('error:', item)
        break

if (set(colors)-set(lstColor)):        #转换为集合之后再比较
    print('error')

例4 电影评分与推荐。
问题描述:假设已有大量用户对若干电影的评分数据,现有某用户,也看过一些电影并进行过评分,要求根据已有打分数据为该用户进行推荐。
基本思路:用基于用户的协同过滤算法,也就是根据用户喜好来确定与当前用户最相似的用户,然后再根据最相似用户的喜好为当前用户进行推荐。本例采用字典来存放打分数据,格式为{用户1:{电影名称1:打分1, 电影名称2:打分2,…}, 用户2:{…}},首先在已有数据中查找与当前用户共同打分电影(使用集合的交集运算)数量最多的用户,如果有多个这样的用户就再从中选择打分最接近(打分的差距最小)的用户。代码中使用到了random模块中的randrange()函数,用来生成指定范围内的一个随机数。

from random import randrange

#历史电影打分数据,一共10个用户,每个用户对3到9个电影进行评分
#每个电影的评分最低1分最高5分,这里是字典推导式和集合推导式的用法
data = {'user'+str(i):{'film'+str(randrange(1, 15)):randrange(1, 6)
                          for j in range(randrange(3, 10))}
        for i in range(10)}
#模拟当前用户打分数据,为5部随机电影打分
user = {'film'+str(randrange(1, 15)):randrange(1,6) for i in range(5)}
#最相似的用户及其对电影打分情况
#两个用户共同打分的电影最多
#并且所有电影打分差值的平方和最小
f = lambda item:(-len(item[1].keys()&user),
                   sum(((item[1].get(film)-user.get(film))**2
                        for film in user.keys()&item[1].keys())))
similarUser, films = min(data.items(), key=f)
#在输出结果中,第一列表示两个人共同打分的电影的数量
#第二列表示二人打分之间的相似度,数字越小表示越相似
#然后是该用户对电影的打分数据
print('known data'.center(50, '='))
for item in data.items():
    print(len(item[1].keys()&user.keys()),
          sum(((item[1].get(film)-user.get(film))**2
               for film in user.keys()&item[1].keys())),
          item,
          sep=':')
print('current user'.center(50, '='))
print(user)
print('most similar user and his films'.center(50, '='))
print(similarUser, films, sep=':')
print('recommended film'.center(50, '='))
#在当前用户没看过的电影中选择打分最高的进行推荐
print(max(films.keys()-user.keys(), key=lambda film: films[film]))
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr顺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值