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

Bjö*_*lex 6 python collections

集合和列表在Python中的处理方式不同,似乎没有统一的方法可以同时使用它们.例如,set使用该add方法完成向a添加项目,并且list使用该append方法完成.我知道这背后有不同的语义,但也存在常见的语义,并且通常与某些集合一起使用的算法更多地关注共性而不是差异.C++ STL表明这可以工作,为什么Python中没有这样的概念?

编辑:在C++中,我可以使用an output_iterator来存储(几乎)任意类型的集合中的值,包括列表和集合.我可以编写一个算法,它将这样的迭代器作为参数并将元素写入其中.然后,该算法完全不知道支持迭代器的容器(或其他设备,可能是文件)的类型.如果后备容器是忽略重复项的集合,那么这是调用者的决定.我的具体问题是,现在我已经多次使用过,例如我用于list某个任务,后来认为set更合适.现在我必须在我的代码中的几个地方更改appendto add.我只是想知道为什么Python没有这种情况的概念.

Gle*_*ard 6

The direct answer: it's a design flaw.

You should be able to insert into any container where generic insertion makes sense (eg. excluding dict) with the same method name. There should be a consistent, generic name for insertion, eg. add, corresponding to set.add and list.append, so you can add to a container without having to care as much about what you're inserting into.

Using different names for this operation in different types is a gratuitous inconsistency, and sets a poor base standard: the library should encourage user containers to use a consistent API, rather than providing largely incompatible APIs for each basic container.

也就是说,在这种情况下,它通常不是一个实际问题:大多数情况下,函数的结果是项目列表,将其实现为生成器.它们允许一致地(从函数的角度)处理这两者,以及其他形式的迭代:

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
Run Code Online (Sandbox Code Playgroud)

  • 这完全符合Python中使用的一个相当基本的概念:duck typing.一般来说,你应该能够在没有特别关心它们的情况下操作物体; 如果给你一个容器你不关心 - 除非你有特定的理由 - 无论是列表或集合,还是用户提供的链表,二叉树,BSP树或其他任何东西.对这些方法使用不同的名称会不必要地违背这种设计理念,并迫使您关心您正在使用的内容. (2认同)