在Python中,集合和列表的处理方式不同,似乎没有统一的方法可以同时使用它们。例如,使用set
方法向add
添加项目,而list
使用append
方法完成。我知道这背后有不同的语义,但也存在常见的语义,并且通常与某些集合一起使用的算法更多地关注共性而不是差异。 C ++ STL表明这可行,所以为什么Python中没有这样的概念?
编辑:在C ++中,我可以使用output_iterator
将值存储在(几乎)任意类型的集合中,包括列表和集合。我可以编写一个算法,它将这样的迭代器作为参数并将元素写入其中。然后,该算法完全不知道支持迭代器的容器(或其他设备,可能是文件)的类型。如果后备容器是忽略重复项的集合,那么这是调用者的决定。我的具体问题是,现在我已经多次使用过list
来执行某项任务,后来认为set
更合适。现在,我必须在代码中的几个位置将append
更改为add
。我只是想知道为什么Python对这种情况没有概念。
答案 0 :(得分:6)
直接回答:这是一个设计缺陷。
您应该能够使用相同的方法名称插入任何通用插入有意义的容器(例如,排除dict)。插入应该有一致的通用名称,例如。 add
,对应set.add
和list.append
,因此您可以添加到容器中,而无需关心插入的内容。
在不同类型中对此操作使用不同的名称是无偿的不一致,并设置了较差的基本标准:库应该鼓励用户容器使用一致的API,而不是为每个基本容器提供大部分不兼容的API。
也就是说,在这种情况下,这通常不是一个实际问题:大多数情况下,函数的结果是项目列表,将其实现为生成器。它们允许一致地(从函数的角度)处理这两者,以及其他形式的迭代:
def foo():
yield 1
yield 2
yield 3
s = set(foo())
l = list(foo())
results1 = [i*2 for i in foo()]
results2 = (i*2 for i in foo())
for r in foo():
print r
答案 1 :(得分:4)
添加和附加 不同。集合是无序的并且包含唯一元素,而追加表示项目总是被添加,并且这是在最后特别完成的。
集合和列表都可以被视为可迭代,这是它们的常用语义,并且您的算法可以自由使用。
如果你的算法依赖于某种类型的添加,你就不能依赖于集合,元组,列表,字符串,行为相同的字符串。
答案 2 :(得分:1)
实际原因可能与Python历史有关。
内置集类型不是built-in until Python 2.6,而是基于集合模块,在Python 2.3之前,它本身不在标准库中。显然,改变集合类型的语义可能会破坏依赖于原始集合模块的大量现有代码,并且通常语言设计者不会在没有主要版本发布的情况下破坏现有代码。
如果您愿意,可以责怪原始模块作者,但请记住,在Python 2.2之前,用户定义的类型和内置类型必然存在于不同的Universe中,这意味着您无法直接扩展内置类型,并且可能允许模块作者感觉不能保持一致的集合语义。