<p>获取唯一项集合的常用方法是使用<a href="http://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset" rel="noreferrer">^{<cd1>}</a>。集合是不同对象的无序集合。要从任何iterable创建集合,只需将其传递给内置的<a href="http://docs.python.org/3/library/functions.html#func-set" rel="noreferrer">^{<cd2>}</a>函数。如果以后再次需要一个真正的列表,您可以类似地将集合传递给<a href="http://docs.python.org/3/library/functions.html#func-list" rel="noreferrer">^{<cd3>}</a>函数。</p>
<p>下面的例子应该包括您要做的任何事情:</p>
<pre><code>>>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> t
[1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> list(set(t))
[1, 2, 3, 5, 6, 7, 8]
>>> s = [1, 2, 3]
>>> list(set(t) - set(s))
[8, 5, 6, 7]
</code></pre>
<p>从示例结果中可以看到,<em>原始顺序不会保持</em>。如上所述,集合本身是无序集合,因此顺序丢失。将集合转换回列表时,将创建任意顺序。</p>
<h3>维持秩序</h3>
<p>如果顺序对你很重要,那么你就必须使用不同的机制。一个非常常见的解决方案是依赖<a href="https://docs.python.org/3/library/collections.html#collections.OrderedDict" rel="noreferrer">^{<cd4>}</a>在插入期间保持键的顺序:</p>
<pre><code>>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]
</code></pre>
<p><a href="https://mail.python.org/pipermail/python-dev/2017-December/151283.html" rel="noreferrer">Starting with Python 3.7</a>,内置字典也可以保证保持插入顺序,因此如果您使用的是Python 3.7或更高版本(或cpython3.6),也可以直接使用它:</p>
<pre><code>>>> list(dict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]
</code></pre>
<p>注意,首先创建字典,然后从中创建列表可能会有一些开销。如果实际上不需要维护顺序,那么使用集合通常会更好,特别是因为它可以为您提供更多的操作。查看<a href="https://stackoverflow.com/q/480214/216074">this question</a>了解更多详细信息,以及在删除重复项时保留顺序的其他方法。</p>
<hr/>
<p>最后请注意,<code>set</code>和<code>OrderedDict</code>/<code>dict</code>解决方案都要求您的项是可散列的。这通常意味着它们必须是不可变的。如果必须处理不可散列的项(例如列表对象),则必须使用慢速方法,在这种方法中,基本上必须将每个项与嵌套循环中的每个其他项进行比较。</p>