Python 关于set的数字元素的顺序问题

无序的这个是str.isspace,看似有序的是str.isascii,除了shell输入set的变量,是有序显示,但是无论是str()还是repr()还是list(),并非顺序显示

print(d['isspace'])
{
    
    5760, 8192, 8194, 8195, 8193, 133, 8196, 8197, 8198, 9, 10, 11, 12, 13, 8199, 8200, 8201, 8202, 12288, 28, 29, 30, 31, 32, 160, 8232, 8233, 8239, 8287}

print(d['isascii'])
{
    
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}

s='isspace'
r=set()
f=eval('str.%s'%s)
for i in range(0x110000):
    if f(chr(i)):r.add(i)
    
r
Out[95]: 
{
    
    9,
 10,
 11,
 12,
 13,
 28,
 29,
 30,
 31,
 32,
 133,
 160,
 5760,
 8192,
 8193,
 8194,
 8195,
 8196,
 8197,
 8198,
 8199,
 8200,
 8201,
 8202,
 8232,
 8233,
 8239,
 8287,
 12288}

猜测上面是使用了不定长的hash值,虽然我使用python的hash函数,正整数的话,数值就是他本身,如果是按照其进行排序的话,应该是顺序,要么不是这种hash表。总之,相挨的数倒是顺序的。

但奇妙的事情:

s=set()
for i in range(100,10,-5):
    s.add(i)
repr(s)
Out[106]: '{65, 35, 100, 70, 40, 75, 45, 15, 80, 50, 20, 85, 55, 25, 90, 60, 30, 95}'
sys.getsizeof(s)
Out[165]: 728
for i in range(10,15):
    s.add(i)
repr(s)
Out[109]: '{10, 11, 12, 13, 14, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100}'
sys.getsizeof(s)
Out[166]: 2264
for i in range(10,15):
    s.remove(i)
repr(s)
Out[115]: '{15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100}'
sys.getsizeof(s)
Out[167]: 2264

开始时,我使用了倒叙的赋值,顺序是乱的,之后复制了一串数,顺序挣了,之后移除了那些数,数居然还是有序的

之后我获取了集合的大小,最开始集合的大小是728,乱序,增加了5个元素后,顺序,大小2264,去掉这5个元素后,仍是顺序,大小仍是2264。

那么最初的集合和现在的集合一样吗?

s1=set()
for i in range(100,10,-5):
    s1.add(i)

s1==s
Out[169]: True

repr(s1)
Out[170]: '{65, 35, 100, 70, 40, 75, 45, 15, 80, 50, 20, 85, 55, 25, 90, 60, 30, 95}'

repr(s)
Out[171]: '{15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100}'

自然是一样的,但内部结构却不一样

前后使用了不同量级的哈希表,在这个哈希表中,一个单元覆盖了所有的数值,所以这一段数值是顺序的,这个集合貌似可以直接当作顺序的复合类型使用。

但是,如果加入的元素无法让哈希表量级变化,仍是散的单元,这堆数据就是看似乱序的,虽然有一小块一小块的顺序。

结论就是,如果是完全步进1的顺序序列,可以用set排序,但这依旧是旁门左道。如果有步进,你是无法确定生成的set内部是否是顺序的!

猜你喜欢

转载自blog.csdn.net/jhsxy2005/article/details/113727022
今日推荐