【发布时间】:2011-05-26 11:21:33
【问题描述】:
我在 Python 中有一个列表,我怎样才能使它的值唯一?
【问题讨论】:
标签: python
我在 Python 中有一个列表,我怎样才能使它的值唯一?
【问题讨论】:
标签: python
Python中集合的特点是集合中的数据项 是无序的,不允许重复。如果您尝试将数据项添加到已包含该数据项的集合中,Python 会简单地忽略它。
>>> l = ['a', 'a', 'bb', 'b', 'c', 'c', '10', '10', '8','8', 10, 10, 6, 10, 11.2, 11.2, 11, 11]
>>> distinct_l = set(l)
>>> print(distinct_l)
set(['a', '10', 'c', 'b', 6, 'bb', 10, 11, 11.2, '8'])
【讨论】:
字典理解怎么样?
>>> mylist = [3, 2, 1, 3, 4, 4, 4, 5, 5, 3]
>>> {x:1 for x in mylist}.keys()
[1, 2, 3, 4, 5]
编辑 对于@Danny 的评论:我最初的建议并没有让钥匙保持有序。如果您需要对键进行排序,请尝试:
>>> from collections import OrderedDict
>>> OrderedDict( (x,1) for x in mylist ).keys()
[3, 2, 1, 4, 5]
通过元素的第一次出现来保持元素的顺序(未经广泛测试)
【讨论】:
OrderedDict 和生成器的示例。
我举个例子给你解释一下:
如果你有 Python 列表
>>> randomList = ["a","f", "b", "c", "d", "a", "c", "e", "d", "f", "e"]
并且您想从中删除重复项。
>>> uniqueList = []
>>> for letter in randomList:
if letter not in uniqueList:
uniqueList.append(letter)
>>> uniqueList
['a', 'f', 'b', 'c', 'd', 'e']
这是您可以从列表中删除重复项的方法。
【讨论】:
单线并保持秩序
list(OrderedDict.fromkeys([2,1,1,3]))
虽然你需要
from collections import OrderedDict
【讨论】:
在保留顺序的同时删除重复项的最简单方法是使用collections.OrderedDict(Python 2.7+)。
from collections import OrderedDict
d = OrderedDict()
for x in mylist:
d[x] = True
print d.iterkeys()
【讨论】:
http://www.peterbe.com/plog/uniqifiers-benchmark的修改版
为了保持顺序:
def f(seq): # Order preserving
''' Modified version of Dave Kirby solution '''
seen = set()
return [x for x in seq if x not in seen and not seen.add(x)]
好的,现在它是如何工作的,因为这里有点棘手if x not in seen and not seen.add(x):
In [1]: 0 not in [1,2,3] and not print('add')
add
Out[1]: True
为什么它返回 True? print(和 set.add)什么都不返回:
In [3]: type(seen.add(10))
Out[3]: <type 'NoneType'>
和not None == True,但是:
In [2]: 1 not in [1,2,3] and not print('add')
Out[2]: False
为什么它在 [1] 中打印 'add' 而不是在 [2] 中?参见False and print('add'),并且不检查第二个参数,因为它已经知道答案,并且只有当两个参数都为真时才返回真。
更通用的版本,更易读,基于生成器,增加了使用函数转换值的能力:
def f(seq, idfun=None): # Order preserving
return list(_f(seq, idfun))
def _f(seq, idfun=None):
''' Originally proposed by Andrew Dalke '''
seen = set()
if idfun is None:
for x in seq:
if x not in seen:
seen.add(x)
yield x
else:
for x in seq:
x = idfun(x)
if x not in seen:
seen.add(x)
yield x
无序(更快):
def f(seq): # Not order preserving
return list(set(seq))
【讨论】:
如果列表的所有元素都可以用作字典键(即它们都是可散列的),这通常会更快。 Python Programming FAQ
d = {}
for x in mylist:
d[x] = 1
mylist = list(d.keys())
【讨论】:
为了保持顺序:
l = [1, 1, 2, 2, 3]
result = list()
map(lambda x: not x in result and result.append(x), l)
result
# [1, 2, 3]
【讨论】:
来自http://www.peterbe.com/plog/uniqifiers-benchmark:
def f5(seq, idfun=None):
# order preserving
if idfun is None:
def idfun(x): return x
seen = {}
result = []
for item in seq:
marker = idfun(item)
# in old Python versions:
# if seen.has_key(marker)
# but in new ones:
if marker in seen: continue
seen[marker] = 1
result.append(item)
return result
【讨论】:
最简单的方法是先转换为集合,然后再转换为列表:
my_list = list(set(my_list))
这样做的一个缺点是它不会保留订单。您可能还想首先考虑使用集合而不是列表是否是一种更好的数据结构。
【讨论】:
[23]: from functools import reduceIn [24]: reduce(lambda acc,elem: acc+[elem] if not elem in acc else acc , [2,1,2,3,3,3,4,5], [])Out[24]: [2, 1, 3, 4, 5]