我想从以下列表中获取唯一值:
['nowplaying', 'PBS', 'PBS', 'nowplaying', 'job', 'debate', 'thenandnow']
Run Code Online (Sandbox Code Playgroud)
我需要的输出是:
['nowplaying', 'PBS', 'job', 'debate', 'thenandnow']
Run Code Online (Sandbox Code Playgroud)
此代码有效:
output = []
for x in trends:
if x not in output:
output.append(x)
print(output)
Run Code Online (Sandbox Code Playgroud)
我应该使用更好的解决方案吗?
lef*_*rav 913
首先正确声明您的列表,用逗号分隔.您可以通过将列表转换为集合来获取唯一值.
mylist = ['nowplaying', 'PBS', 'PBS', 'nowplaying', 'job', 'debate', 'thenandnow']
myset = set(mylist)
print(myset)
Run Code Online (Sandbox Code Playgroud)
如果您进一步将其用作列表,则应通过执行以下操作将其转换回列表:
mynewlist = list(myset)
Run Code Online (Sandbox Code Playgroud)
另一种可能性,可能更快,就是从头开始使用一个集合,而不是列表.那你的代码应该是:
output = set()
for x in trends:
output.add(x)
print(output)
Run Code Online (Sandbox Code Playgroud)
正如已经指出的那样,集合不保持原始顺序.如果您需要,您应该查看有序集.
ale*_*mol 294
为了与我使用的类型保持一致:
mylist = list(set(mylist))
Run Code Online (Sandbox Code Playgroud)
Tod*_*dor 88
如果我们需要保持元素顺序,那么这个怎么样:
used = set()
mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = [x for x in mylist if x not in used and (used.add(x) or True)]
Run Code Online (Sandbox Code Playgroud)
还有一个使用reduce和不使用临时used变量的解决方案.
mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = reduce(lambda l, x: l.append(x) or l if x not in l else l, mylist, [])
Run Code Online (Sandbox Code Playgroud)
更新 - 2016年10月1日
另一个解决方案.index,但这次没有reduce它使它更易于阅读和理解.
mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = [x for i, x in enumerate(mylist) if i == mylist.index(x)]
Run Code Online (Sandbox Code Playgroud)
注意:请记住,我们得到的人类可读性更高,脚本更难以理解.
mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = reduce(lambda l, x: l+[x] if x not in l else l, mylist, [])
#which can also be writed as:
unique = reduce(lambda l, x: l if x in l else l+[x], mylist, [])
Run Code Online (Sandbox Code Playgroud)
回答评论
因为@monica问了一个关于"这怎么工作?"的好问题.对于每个有问题的人来说.我将尝试更深入地解释这是如何工作的以及这里发生的巫术;)
所以她先问:
我试着理解为什么
.append不起作用.
嗯,它实际上工作
import timeit
setup = "mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']"
#10x to Michael for pointing out that we can get faster with set()
timeit.timeit('[x for x in mylist if x not in used and (used.add(x) or True)]', setup='used = set();'+setup)
0.4188511371612549
timeit.timeit('[x for x in mylist if x not in used and (used.append(x) or True)]', setup='used = [];'+setup)
0.6157128810882568
timeit.timeit('reduce(lambda l, x: l.append(x) or l if x not in l else l, mylist, [])', setup=setup)
1.8778090476989746
timeit.timeit('reduce(lambda l, x: l+[x] if x not in l else l, mylist, [])', setup=setup)
2.13108491897583
timeit.timeit('reduce(lambda l, x: l if x in l else l+[x], mylist, [])', setup=setup)
2.207760810852051
timeit.timeit('[x for i, x in enumerate(mylist) if i == mylist.index(x)]', setup=setup)
2.3621110916137695
Run Code Online (Sandbox Code Playgroud)
问题是我们只是没有在unique = [used.append(x) for x in mylist if x
not in used]变量中获得所需的结果,而只是在unique变量内部.这是因为在列表理解期间used修改.append变量并返回used.
因此,为了将结果输入None变量,并且仍然使用相同的逻辑unique,我们需要.append(x) if x not in used在列表推导的右侧移动此调用,然后返回.append左侧.
但是,如果我们太天真,只需要:
>>> used = []
>>> mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
>>> unique = [used.append(x) for x in mylist if x not in used]
>>> print used
[u'nowplaying', u'PBS', u'job', u'debate', u'thenandnow']
>>> print unique
[None, None, None, None, None]
Run Code Online (Sandbox Code Playgroud)
我们什么也得不到回报.
同样,这是因为该x方法返回.append,并且这给我们的逻辑表达式提供了以下外观:
>>> unique = [x for x in mylist if x not in used and used.append(x)]
>>> print unique
[]
Run Code Online (Sandbox Code Playgroud)
这基本上总是:
None何时False进入x,used何时None不在x.在两种情况下(used/ False),这将被视为None值,我们将得到一个空列表作为结果.
但为什么这个评估falsy时间None不在x?有人可能会问.
表达式
used首先评估x; 如果x为false,则返回其值; 否则,将评估y并返回结果值.
因此,当x and y未使用时(即,当它x)时,下一部分或表达式将被计算(True)并且将返回其值(used.append(x)).
但这就是我们想要的,以便从列表中获取具有重复项的独特元素,我们希望None它们只有在我们遇到的时候才会进入新列表.
所以我们真的只想.append在used.append(x)不在的时候进行评估x,也许如果有办法将这个used值变成None一个我们会好的,对吗?
嗯,是的,这里是第二类truthy运营商发挥作用的地方.
表达式
short-circuit首先评估x; 如果x为真,则返回其值; 否则,将评估y并返回结果值.
我们知道x or y永远都是.append(x),所以如果我们只是falsy在他旁边添加一个,我们将永远得到下一部分.这就是为什么我们写:
x not in used and None
Run Code Online (Sandbox Code Playgroud)
所以我们可以评估 or并得到used.append(x)结果,只有表达式的第一部分True是(x not in used).
在第二种方法中可以看到类似的True方式.
x not in used and (used.append(x) or True)
Run Code Online (Sandbox Code Playgroud)
在哪里我们:
reduce到x并返回l时l不x.感谢l语句or被评估并.append在此之后返回.l时,不变l是xSam*_*zzo 86
你的输出变量是什么类型的?
Python 集是您所需要的.声明输出如下:
output = set() # initialize an empty set
Run Code Online (Sandbox Code Playgroud)
你准备好添加元素,output.add(elem)并确保它们是独一无二的.
警告:设置不保留列表的原始顺序.
Nic*_*bey 77
您提供的示例与Python中的列表不对应.它类似于嵌套的字典,可能不是你想要的.
Python列表:
>>> a = ['a', 'b', 'c', 'd', 'b']
Run Code Online (Sandbox Code Playgroud)
要获取唯一项目,只需将其转换为一个集合(如果需要,您可以将其转换回列表):
>>> b = set(a)
>>> print(b)
{'b', 'c', 'd', 'a'}
Run Code Online (Sandbox Code Playgroud)
dai*_*no3 41
维持秩序:
# oneliners
# slow -> . --- 14.417 seconds ---
[x for i, x in enumerate(array) if x not in array[0:i]]
# fast -> . --- 0.0378 seconds ---
[x for i, x in enumerate(array) if array.index(x) == i]
# multiple lines
# fastest -> --- 0.012 seconds ---
uniq = []
[uniq.append(x) for x in array if x not in uniq]
uniq
Run Code Online (Sandbox Code Playgroud)
订单无关紧要:
# fastest-est -> --- 0.0035 seconds ---
list(set(array))
Run Code Online (Sandbox Code Playgroud)
pyl*_*ang 19
删除重复项的选项可能包括以下通用数据结构:
这是关于快速使用Python之一的摘要。
给定
from collections import OrderedDict
seq = [u"nowplaying", u"PBS", u"PBS", u"nowplaying", u"job", u"debate", u"thenandnow"]
Run Code Online (Sandbox Code Playgroud)
码
选项1-一组(无序):
list(set(seq))
# ['thenandnow', 'PBS', 'debate', 'job', 'nowplaying']
Run Code Online (Sandbox Code Playgroud)
选项2 -Python没有排序集,但是这里有一些模仿一个(插入排序)的方法:
list(OrderedDict.fromkeys(seq))
# ['nowplaying', 'PBS', 'job', 'debate', 'thenandnow']
Run Code Online (Sandbox Code Playgroud)
list(dict.fromkeys(seq)) # py36
# ['nowplaying', 'PBS', 'job', 'debate', 'thenandnow']
Run Code Online (Sandbox Code Playgroud)
如果使用Python 3.6+,建议使用最后一个选项。
注意:列出的元素必须是可哈希的。请参阅此博客文章中有关后一个示例的详细信息。此外,请参见R. Hettinger 关于相同技术的文章。保留顺序字典是他早期实现之一。另请参见有关总订购的更多信息。
s_m*_*_mj 19
从列表中获取独特元素
mylist = [1,2,3,4,5,6,6,7,7,8,8,9,9,10]
Run Code Online (Sandbox Code Playgroud)
使用集合中的简单逻辑 - 集合是唯一的项目列表
mylist=list(set(mylist))
In [0]: mylist
Out[0]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Run Code Online (Sandbox Code Playgroud)
使用简单逻辑
newList=[]
for i in mylist:
if i not in newList:
newList.append(i)
In [0]: mylist
Out[0]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Run Code Online (Sandbox Code Playgroud)
使用pop方法 - > pop删除最后一个或索引项并将其显示给用户.视频
k=0
while k < len(mylist):
if mylist[k] in mylist[k+1:]:
mylist.pop(mylist[k])
else:
k=k+1
In [0]: mylist
Out[0]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Run Code Online (Sandbox Code Playgroud)
使用Numpy
import numpy as np
np.unique(mylist)
In [0]: mylist
Out[0]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Run Code Online (Sandbox Code Playgroud)
Mul*_*mer 16
set - 无序的独特元素集合.元素列表可以传递给set的构造函数.因此,传递具有重复元素的列表,我们使用唯一元素进行设置并将其转换回列表然后获取具有唯一元素的列表.我不能说性能和内存开销,但我希望,对于小型列表来说并不是那么重要.
list(set(my_not_unique_list))
Run Code Online (Sandbox Code Playgroud)
简单而简短.
小智 15
如果你在代码中使用numpy(对于大量数据可能是一个不错的选择),请查看numpy.unique:
>>> import numpy as np
>>> wordsList = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
>>> np.unique(wordsList)
array([u'PBS', u'debate', u'job', u'nowplaying', u'thenandnow'],
dtype='<U10')
Run Code Online (Sandbox Code Playgroud)
(http://docs.scipy.org/doc/numpy/reference/generated/numpy.unique.html)
如您所见,numpy不仅支持数字数据,还支持字符串数组.当然,结果是一个numpy数组,但它并不重要,因为它仍然表现得像一个序列:
>>> for word in np.unique(wordsList):
... print word
...
PBS
debate
job
nowplaying
thenandnow
Run Code Online (Sandbox Code Playgroud)
如果你真的想要一个vanilla python列表,你可以随时调用list().
但是,结果会自动排序,您可以从上面的代码片段中看到.如果需要保留列表顺序,请检查numpy unique而不排序.
Odr*_*ded 12
仅使用列表压缩的相同订单唯一列表.
> my_list = [1, 2, 1, 3, 2, 4, 3, 5, 4, 3, 2, 3, 1]
> unique_list = [
> e
> for i, e in enumerate(my_list)
> if my_list.index(e) == i
> ]
> unique_list
[1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)
enumerates给索引i和元素e一个tuple.
my_list.index返回第一个索引e.如果第一个索引不是,i则当前迭代e不是e列表中的第一个.
编辑
我应该注意,这不是一个很好的方法,在性能方面.这只是一种仅使用列表压缩来实现它的方法.
通过使用Python Dictionary的基本属性:
inp=[u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
d={i for i in inp}
print d
Run Code Online (Sandbox Code Playgroud)
输出将是:
set([u'nowplaying', u'job', u'debate', u'PBS', u'thenandnow'])
Run Code Online (Sandbox Code Playgroud)
首先,您提供的示例不是有效列表.
example_list = [u'nowplaying',u'PBS', u'PBS', u'nowplaying', u'job', u'debate',u'thenandnow']
Run Code Online (Sandbox Code Playgroud)
假设上面是示例列表.然后,您可以使用以下配方作为itertools示例文档,该文档可以返回唯一值并保留您看起来需要的顺序.这里的iterable是example_list
from itertools import ifilterfalse
def unique_everseen(iterable, key=None):
"List unique elements, preserving order. Remember all elements ever seen."
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
# unique_everseen('ABBCcAD', str.lower) --> A B C D
seen = set()
seen_add = seen.add
if key is None:
for element in ifilterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
else:
for element in iterable:
k = key(element)
if k not in seen:
seen_add(k)
yield element
Run Code Online (Sandbox Code Playgroud)
小智 6
def get_distinct(original_list):
distinct_list = []
for each in original_list:
if each not in distinct_list:
distinct_list.append(each)
return distinct_list
Run Code Online (Sandbox Code Playgroud)
set可以帮助您筛选出重复列表中的元素.这将很好的工作str,int或tuple元素,但如果你的列表中包含dict或其他list元素,那么你最终会与TypeError例外.
这是一个通用的保留顺序的解决方案来处理一些(不是所有)不可清除的类型:
def unique_elements(iterable):
seen = set()
result = []
for element in iterable:
hashed = element
if isinstance(element, dict):
hashed = tuple(sorted(element.iteritems()))
elif isinstance(element, list):
hashed = tuple(element)
if hashed not in seen:
result.append(element)
seen.add(hashed)
return result
Run Code Online (Sandbox Code Playgroud)
作为奖励,Counter是获取每个值的唯一值和计数的简单方法:
from collections import Counter
l = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
c = Counter(l)
Run Code Online (Sandbox Code Playgroud)
如果你想从列表中获取唯一元素并保持其原始顺序,那么你可以使用OrderedDictPython 标准库中的数据结构:
from collections import OrderedDict\n\ndef keep_unique(elements):\n return list(OrderedDict.fromkeys(elements).keys())\n\nelements = [2, 1, 4, 2, 1, 1, 5, 3, 1, 1]\nrequired_output = [2, 1, 4, 5, 3]\n\nassert keep_unique(elements) == required_output\nRun Code Online (Sandbox Code Playgroud)\n\n事实上,如果您使用的是 Python \xe2\x89\xa5 3.6,则可以使用 plaindict来实现:
def keep_unique(elements):\n return list(dict.fromkeys(elements).keys())\nRun Code Online (Sandbox Code Playgroud)\n\n在引入字典的“紧凑”表示之后,这成为可能。在这里查看一下。尽管这“被认为是实施细节,不应依赖”。
\n| 归档时间: |
|
| 查看次数: |
1376537 次 |
| 最近记录: |