为什么在 python 中设置从具有不同字符编码的字符串列表中选择第一个元素?

Why set in python choose first element from list of string with different character encoding?

为什么set()在Python中添加设置不同字符编码(ASCII、Unicode)的第一个元素? 例如

list1, list2 = [u'string' , 'string'], ['string', u'string']
set1, set2 = set(list1), set(list2)

当我打印 set1 和 set2 时,它们有不同的输出

print(set1)
(set([u'string'])

print(set2)
(set(['string']))

您更改了顺序:[u'string' , 'string'], ['string', u 'string']

在您的情况下,它只是 returns 第一个唯一值 u'string''string'分别

In [7]: list1, list2 = [u'string' , 'string'], [u'string', 'string']

In [8]: set1, set2 = set(list1), set(list1)

In [9]: set1
Out[9]: {u'string'}

In [10]: set2
Out[10]: {u'string'}

首先,set object 保留唯一元素,当您在列表上使用 set 函数时,它会从第一个索引处获取列表中的项目,然后检查是否有任何具有相同 哈希值 的元素则不会将该元素插入集合中。

您可能还注意到 unicode 和 ASCII 字符串具有相同的哈希值!

具有相同 ASCII 内容的 Unicode 和常规字符串获得相同的哈希并被视为相等:

>>> hash(u'string')
-9167918882415130555
>>> hash('string')
-9167918882415130555
>>> u'string' == 'string'
True

将两个 'equal' 对象放入一组结果只剩下一个对象。然后它只在你在字符串中输入的顺序很重要。

在CPython中,第一个对象获胜;在您的示例中,一个将 u'string' 放在第一位,因此将 'string' 添加到同一组没有任何效果,而在另一个示例中 'string' 是第一个,因此添加 u'string' 没有任何效果.

这只适用于str对象都可以解码为ASCII。超出该代码点和上述内容的任何数据都不再适用;无论如何,当您尝试测试相等性时,您甚至会收到特定警告:

>>> 'stringå' == u'stringå'
__main__:1: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
False
>>> 'stringå' in set([u'stringå'])
False
>>> set([u'stringå', 'stringå'])
set([u'string\xe5', 'string\xc3\xa5'])

我的终端恰好设置为 UTF-8,所以在交互式会话中输入 å 最终实际上是 UTF-8 编码的字节序列 C3 A5;这不能解码为 ASCII,因此比较失败并且 strunicode 版本不再测试为相等并且在 set 中显示为单独的对象。 Python 解释器从 UTF-8 自动解码 u'stringå' 以形成 unicode 对象。