为什么在Python中不能统一处理集合?

为什么在Python中不能统一处理集合?,python,collections,Python,Collections,在Python中,集合和列表的处理方式是不同的,而且似乎没有统一的方式来处理这两个集合和列表。例如,使用add方法将项目添加到集合中,对于列表,使用append方法将项目添加到集合中。我知道这背后有不同的语义,但也有共同的语义,通常与某些集合一起工作的算法更关心共性而不是差异。C++ STL表明,这是可行的,那么为什么Python中没有这样的概念? > >编辑: C++中,我可以用AN来存储几乎(任意)类型的集合中的值,包括列表和集合。我可以编写一个算法,将这样一个迭代器作为参数,并将元素写入

在Python中,集合和列表的处理方式是不同的,而且似乎没有统一的方式来处理这两个集合和列表。例如,使用
add
方法将项目添加到
集合中,对于
列表,使用
append
方法将项目添加到集合中。我知道这背后有不同的语义,但也有共同的语义,通常与某些集合一起工作的算法更关心共性而不是差异。C++ STL表明,这是可行的,那么为什么Python中没有这样的概念? <> > >编辑: C++中,我可以用AN来存储几乎(任意)类型的集合中的值,包括列表和集合。我可以编写一个算法,将这样一个迭代器作为参数,并将元素写入其中。然后,该算法完全不知道支持迭代器的容器(或其他设备,可能是文件)的类型。如果备份容器是一个忽略重复项的集合,则这是调用者的决定。我的具体问题是,现在我已经多次遇到这种情况,例如,我为某项任务使用了
列表
,后来决定
设置
更合适。现在,我必须在代码中的几个位置将
append
更改为
add
。我只是想知道为什么Python对这种情况没有概念。

添加和附加是不同的。集合是无序的,并且包含唯一的元素,而append建议始终添加该项,并且这是在末尾专门完成的

集合和列表都可以被视为可重用的,这是它们的通用语义,可以由您的算法自由使用


如果你有一个依赖于某种加法的算法,你就不能依赖于集合、元组、列表、dict、字符串的行为相同。

直接答案:这是一个设计缺陷

您应该能够使用相同的方法名插入到任何通用插入有意义的容器中(例如,排除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

实际原因可能与Python历史有关

内置的set类型不是,而是基于一个set模块,直到python2.3才出现在标准库中。显然,更改集合类型的语义可能会破坏依赖于原始集合模块的大量现有代码,并且通常语言设计人员会避免在不发布大量代码的情况下破坏现有代码


如果愿意,您可以责怪原始模块作者,但请记住,在Python 2.2之前,用户定义的类型和内置类型必然存在于不同的世界中,这意味着您无法直接扩展内置类型,并且可能允许模块作者对不维护一致的集合语义感到满意

“在Python中,集合和列表的处理方式是不同的”,因为它们本质上是不同的。它们不能“统一”,因为——嗯——它们和浮点和文件一样不同。“我知道,有不同的语义”“好的。你要什么?明确地你能给出你认为你想要的更详细的例子吗?@S.Lott:我添加了一个例子和一些说明。“忽略重复项的集合”?什么?那是什么?根据定义,集合不能有重复项。我不明白你在问什么。@S.Lott:set的实现可能选择不忽略重复项,但例如抛出异常或类似的东西。我写这篇文章是为了指出集合的STL实现与Pythons具有相同的行为。“集合的实现可能选择不忽略重复项,但例如抛出异常或类似的东西”好的。但是这种行为与
append
的行为有什么相似之处呢?我看不出
add
append
之间有任何相似之处<代码>添加
可能会更新,或无法更新(或在您的示例中)可能会引发重复的异常<代码>追加
没有这些功能。我觉得完全不同。我想我遗漏了什么。+1:
添加到集合中可能没有任何效果<代码>将
附加到列表中总是有效果的。列表有
扩展
——这对集合意味着什么<代码>工会也许?语义完全不同。C++中的集合也是如此,但是它们有一个统一的元素添加概念(参见我的问题的编辑)。STL提供了许多容器类型。我可以想象你想简化一下。据我所知,当涉及python时,您的问题仅与列表和集合相关。如果您真的需要,您可以编写自己的包装器来包装列表和集合,并按照您希望的方式进行操作。好吧,Python希望是显式的,所以请尝试同时使用一个动词来表示“保留顺序”(对于列表)和“不保留顺序”(对于集合)!几乎不可能-P但正如你所说,实际上有一种统一的方法来构造集合和列表,它比调用
add
append
更具python风格+1美元。