python setup.py install 出错,python setup.py egg_info

大家好,给大家分享一下python setup.py install 出错,很多人还不知道这一点。下面详细解释一下。现在让我们来看看!

 

set是什么

数学上,把set称做由不同的元素组成的集合,集合(set)的成员通常被称做集合元素(set elements)。Python把这个概念引入到它的集合类型对象里火车头小发猫AI伪原创。集合对象是一组无序排列的可哈希的值。集合关系测试和unionintersectiondifference(并集,交集,差集)等操作符在Python里也同样如我们所预想地那样工作。

set的特点

首先python数据结构分为可变和不可变,set属于可变序列

集合中的元素有三个特征:

  1. 确定性:集合中的元素必须是确定的;
  2. 互异性:集合中的元素互不相同,如:集合A={1,a},则a不能等于1);
  3. 无序性:集合中的元素没有先后之分,如:{3,4,5}和{3,5,4}算作同一个集合。

python中集合(set)是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素,还可以计算交集、差集、并集等。它与列表(list)的行为类似,区别在于set不能包含重复的值,而且set元素是无序的

在python中可以用大括号 {} 创建集合。注意:如果要创建或初始化一个空集合,你必须用 set() 而不是 {} 。因为后者{} 作为创建一个空的字典,以后我们会介绍字典这种数据结构。

创建set

创建空集合

s1 = set()  # 创建空集合, 必须用set(),不能用直接用{}创建
print(s1)  # 打印空集合不是{} 而是set(),是为了和空字典区分
print(type(s1))
# set()
# <class 'set'>

d = {}  # 这个是创建空字典,注意区别
print(d, type(d))
# {} <class 'dict'>

创建有元素的集合set

可以自己加入元素创建

也可以利用set()函数从已有的数据结构(列表、字符串、元组)直接转化为集合(主要目的是为了去重)

s1 = {2, 1, 3}
print(s1)  # 下面输出结果看出,集合是无序的
# {1, 2, 3}

s2 = {1, 2, 3, 3}  # 虽然加入的元素有重复,但是集合自动去重
print(s2)
# {1, 2, 3}

# 使用工厂创建集合,但是注意参数是可迭代的
s3 = set('12aa')
print(s3)
# {'1', '2', 'a'}

s4 = set([1, 2, 'a', 'a'])
print(s4)
# {1, 2, 'a'}

s5 = set(((1,2),(3,4),(1,3),(1,2)))
print(s5)
# {(1, 2), (1, 3), (3, 4)}

讨论:

根据上面代码,我们发现,创建空集合只能用set() ,不能用{} 。而且非空集合打印结果是由 {}包裹起来的,前面我们学元组(tuple),它的打印结果是由 () 包裹起来的。另外有第二段代码可以看出集合是无序的,通过set() 可以把其他数据结构转换为集合,而且自动去重。

集合的基本操作函数

  • len(set):集合元素个数
  • max(set):返回集合元素最大值
  • min(set):返回集合元素最小值
  • list(set):将集合转换为列表
  • del:删除集合,释放内存空间

集合添加和删除元素

集合添加元素使用set.add()

集合删除元素使用set.remove()

s1 = {2, 1, 3}
print(s1)
# {1, 2, 3}

s1.add(4)
print(s1)
# {1, 2, 3, 4}

s1.remove(2)
print(s1)
# {1, 3, 4}

注意集合中删除指定元素不要用pop!!

首先pop()只能在可变序列中使用

在列表,字典中都可以用pop(),列表中pop参数是索引,字典中pop参数是key

而set中没有索引也没有key的概念,所以set.pop()中不添加任何参数

而且set.pop()的作用是随机删除集合中的一个元素,它是随即删除,所以其效果非常不可控,建议不要在集合中使用pop()

集合遍历和访问

循环遍历,只能用for循环遍历

# 集合遍历使用for
s1 = {5, 4, 3, 2, 1}
# print(s1)
# # {1, 2, 3, 4, 5}

for x in s1:
    print(x, end=" ")
# 1 2 3 4 5

可以看到上面打印和遍历的结果并不是按照原来集合中输入的顺序

所以再一次说明,集合就是无序的

集合没有索引,不能使用索引获取对应元素,比如使用s[1] 会报错,想想为什么?

s1={1,2,3}
print(s1[1])
# TypeError: 'set' object does not support indexing

因为集合是无序的!所以不肯定不能有索引。如果有索引即代表其是有序的

集合的交并补运算

数学符号Python符号函数版含义
- 或| --difference()差集,相对补集
&intersection()交集
|union()并集
!=不等于
==等于
in是成员关系
not in非成员关系

例子

s1 = {1, 2, 3, 4, 5}
s2 = {4, 5, 6, 7, 8}

print(s1 - s2)  # 差集,等价于s1.difference(s2)
# {1, 2, 3}
print(s2 - s1) # 等价于s2.difference(s1)
# {8, 6, 7}
print(s1 & s2)  # 交集 等价于s1.intersection(s2),s1和s2互换位置也可
# {4, 5}
print(s1 | s2)  # 并集 等价于s1.union(s2),s1和s2互换位置也可
# {1, 2, 3, 4, 5, 6, 7, 8}
print(s1 ^ s2)  # 交叉补集 即并集减去交集
# {1, 2, 3, 6, 7, 8}

print(6 in s1)
# False
print(6 not in s1)
# True

注意函数和符号的用法完全等价,其都会产生一个新的对象,不会对原集合s1和s2进行修改

如果要对集合进行交并补操作并原地修改需要用到赋值操作

# 将s1更新为s1和s2的交集
s1 = {1, 2, 3, 4, 5}
s2 = {4, 5, 6, 7, 8}
s1.intersection(s2)
print(s1)
# {1, 2, 3, 4, 5} 没有对s1进行修改

s1 = s1.intersection(s2) # 一定要用到赋值操作
print(s1)
# {4, 5}

集合类定义的函数

方法描述
add()为集合添加元素
update()给集合添加元素
clear()移除集合中的所有元素
copy()拷贝一个集合
pop()随机移除元素
remove()移除指定元素
discard()删除集合中指定的元素
isdisjoint()判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。
issubset()判断指定集合是否为该方法参数集合的子集。
issuperset()判断该方法的参数集合是否为指定集合的子集
symmetric_difference()返回两个集合中不重复的元素集合。
symmetric_difference_update()移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。
union()返回两个集合的并集,等同于 |
difference()返回多个集合的差集,等同于 -
difference_update()移除集合中的元素,该元素在指定的集合也存在。
intersection()返回集合的交集
intersection_update()返回集合的交集。

例子

s1 = {1, 2, 3}
s1.add(4)
s1.add(3)  # 添加重复元素,自动去重
print(s1)
# {1, 2, 3, 4}

s2 = {3, 4, 5}
s1.update(s2)
print(s1)
# {1, 2, 3, 4, 5}

s1.remove(1)
print(s1)
# {2, 3, 4, 5}

集合各种操作时间复杂度

操作平均情况最坏情况
x in sO(1)O(n)
并集 s|tO(len(s)+len(t))
交集 s&tO(min(len(s), len(t))O(len(s) * len(t))
差集 s-tO(len(s))
s.difference_update(t)O(len(t))
交叉补集 s^tO(len(s))O(len(s) * len(t))
对称差集s.symmetric_difference_update(t)O(len(t))O(len(t) * len(s))

【附加阅读】

底层实现机制,面试常见问题

核心:集合的底层和字典的底层一样,都是哈希表

集合底层数据结构

集合能如此高效,和它的内部的数据结构密不可分。不同于其他数据结构,集合的内部结构是一张哈希表:哈希表内只存储单一的元素。不了解哈希原理和特性的可网上搜索一下,以后我们也会写一些这方面内容。

哈希表插入数据

当向集合中插入数据时,Python会根据通过 hash(valuse) 函数,计算该元素对应的哈希值。得到哈希值(例如为 hash)之后,再结合集合要存储数据的个数(例如 n),就可以得到该元素应该插入到哈希表中的位置(比如用 取模法 hash%n 方式)。

如果哈希表中此位置是空的,那么此元素就可以直接插入其中;反之,如果此位置已被其他元素占用,那么 Python 会比较这两个元素的哈希值是否相等:

重点:

  • 如果相等,则表明该元素已经存在,再比较他们的值,不相等就进行更新;
  • 如果不相等,这种情况称为哈希冲突(即两个元素的键不同,但求得的哈希值相同)。这种情况下,Python 会使用开放定址法、再哈希法等继续寻找哈希表中空余的位置,直到找到位置。

哈希表查找数据

在哈希表中查找数据,和插入操作类似,Python 会根据哈希值,找到该元素应该存储到哈希表中的位置,然后和该位置的元素比较元素值:

  • 如果相等,则证明找到;反之,则证明当初存储该元素时,遇到了哈希冲突,需要继续使用当初解决哈希冲突的方法进行查找,直到找到该元素或者找到空位为止。 这里的找到空位,表示哈希表中没有存储目标元素。
  • 反之,则证明当初存储该元素时,遇到了哈希冲突,需要继续使用当初解决哈希冲突的方法进行查找,直到找到该元素或者找到空位为止。 这里的找到空位,表示哈希表中没有存储目标元素。

哈希表删除元素

对于删除操作,Python 会暂时对这个位置的元素赋于一个特殊的值,等到重新调整哈希表的大小时,再将其删除。

重点:

  • 需要注意的是,哈希冲突的发生往往会降低字典和集合操作的速度
  • 因此,为了保证其高效性,字典和集合内的哈希表,通常会保证其至少留有 1/3 的剩余空间。
  • 随着元素的不停插入,当剩余空间小于 1/3 时,Python 会重新获取更大的内存空间,扩充哈希表,与此同时,表内所有的元素位置都会被重新排放。

虽然哈希冲突和哈希表大小的调整,都会导致速度减缓,但是这种情况发生的次数极少。所以,平均情况下,仍能保证插入、查找和删除的时间复杂度为 O(1)。

set 怎么判断两个元素是不是重复,怎么去重的?

set的去重是通过两个函数**__hash____eq__**结合实现的。

当两个元素的哈希值不相同时,就认为这两个变量是不同的
当两个元素哈希值一样时,调用**__eq__**方法,当返回值为True时认为这两个变量是同一个,应该去除一个。返回FALSE时,不去重。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值