【问题标题】:Get unique values from a list in python [duplicate]从python中的列表中获取唯一值[重复]
【发布时间】:2012-10-05 12:43:35
【问题描述】:

我想从以下列表中获取唯一值:

['nowplaying', 'PBS', 'PBS', 'nowplaying', 'job', 'debate', 'thenandnow']

我需要的输出是:

['nowplaying', 'PBS', 'job', 'debate', 'thenandnow']

此代码有效:

output = []
for x in trends:
    if x not in output:
        output.append(x)
print(output)

我应该使用更好的解决方案吗?

【问题讨论】:

  • 顺序重要吗? IE。你想要第一次出现的顺序,还是 ["PBS", "debate", "job", "thenandnow", "nowplaying"] 也可以?
  • 所有顶级解决方案都适用于该问题的示例,但它们不回答问题。它们都使用set,这取决于列表中找到的类型。例如:d = dict();l = list();l.append (d);set(l) 将导致 TypeError: unhashable type: 'dictfrozenset 不会救你。以真正的 Python 方式学习它:实现一个嵌套的 n^2 循环,用于从列表中删除重复项的简单任务。您可以,然后将其优化为 n.log n。或者为您的对象实现真正的散列。或者在为它创建集合之前编组你的对象。
  • 如果需要保留列表的顺序:unique_items = list(dict.fromkeys(list_with_duplicates)) (CPython 3.6+)

标签: python list


【解决方案1】:

如果我们需要保持元素的顺序,这样怎么样:

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)]

还有一种使用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, [])

更新 - 2020 年 12 月 - 也许是最好的方法!

从 python 3.7 开始,标准 dict 保留插入顺序。

在 3.7 版中更改:保证字典顺序为插入顺序。这种行为是 CPython 3.6 的实现细节。

所以这使我们能够使用dict.from_keys 进行重复数据删除!

注意:感谢 @rlat 在 cmets 中为我们提供了这种方法!

mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = list(dict.fromkeys(mylist))

在速度方面 - 对我来说它足够快且可读性足以成为我最喜欢的新方法!

更新 - 2019 年 3 月

还有第三种解决方案,这是一个简洁的解决方案,但有点慢,因为 .index 是 O(n)。

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)]

更新 - 2016 年 10 月

另一个使用reduce 的解决方案,但这次没有.append,这使得它更易于阅读和理解。

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, [])

注意:请记住,我们获得的可读性越高,脚本的性能就越差。除了特定于 python 3.7+ 的 dict.from_keys 方法。

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.2029558869980974

timeit.timeit('[x for x in mylist if x not in used and (used.append(x) or True)]', setup='used = [];'+setup)
0.28999493700030143

# 10x to rlat for suggesting this approach!   
timeit.timeit('list(dict.fromkeys(mylist))', setup=setup)
0.31227896199925453

timeit.timeit('reduce(lambda l, x: l.append(x) or l if x not in l else l, mylist, [])', setup='from functools import reduce;'+setup)
0.7149233570016804

timeit.timeit('reduce(lambda l, x: l+[x] if x not in l else l, mylist, [])', setup='from functools import reduce;'+setup)
0.7379565160008497

timeit.timeit('reduce(lambda l, x: l if x in l else l+[x], mylist, [])', setup='from functools import reduce;'+setup)
0.7400134069976048

timeit.timeit('[x for i, x in enumerate(mylist) if i == mylist.index(x)]', setup=setup)
0.9154880290006986

回答评论

因为 @monica 提出了一个关于“这是如何工作的?”的好问题。对于每个有问题的人。我将尝试更深入地解释它是如何工作的以及这里发生了什么巫术;)

于是她先问:

我试图理解为什么unique = [used.append(x) for x in mylist if x not in used] 不起作用。

它确实有效

>>> 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]

问题是我们在unique 变量中没有得到想要的结果,而只是在used 变量中。这是因为在列表解析期间.append 修改了used 变量并返回None

因此,为了将结果放入unique 变量中,并且仍然使用与.append(x) if x not in used 相同的逻辑,我们需要将这个.append 调用移动到列表理解的右侧并返回@987654347 @在左侧。

但是如果我们太天真了,那就去吧:

>>> unique = [x for x in mylist if x not in used and used.append(x)]
>>> print unique
[]

我们不会得到任何回报。

同样,这是因为.append 方法返回None,这使得我们的逻辑表达式如下所示:

x not in used and None

这基本上总是:

  1. xused 中时计算为False
  2. x 不在used 中时评估为None

在这两种情况下 (False/None),这将被视为 falsy 值,因此我们将得到一个空列表。

但是当x 不在used 中时,为什么它的计算结果为None?有人可能会问。

这是因为这就是 Python 的 short-circuit 运算符 works 的方式。

表达式x and y首先计算x;如果 x 为假,则其值为 回来;否则,对 y 求值,结果值为 返回。

所以当x 没有被使用时(即当它的True下一部分或表达式将被评估(used.append(x))和它的值 (None) 将被返回。

但这就是我们想要从具有重复项的列表中获取唯一元素的目的,我们希望仅当我们第一次遇到它们时才将它们 .append 放入一个新列表中。

所以我们真的只想在x 不在used 中时评估used.append(x),也许如果有办法将这个None 值变成truthy 值,我们会没事的,对吧?

嗯,是的,这就是第二类short-circuit 运算符的作用所在。

表达式x or y首先计算x;如果 x 为真,则其值为 回来;否则,对 y 求值,结果值为 返回。

我们知道.append(x) 永远是falsy,所以如果我们只在他旁边添加一个or,我们总是会得到下一部分。这就是我们写作的原因:

x not in used and (used.append(x) or True)

所以我们可以评估 used.append(x) 并得到True 结果,仅当表达式的第一部分(x not in used)True

reduce 方法的第二种方法中可以看到类似的方式。

(l.append(x) or l) if x not in l else l
#similar as the above, but maybe more readable
#we return l unchanged when x is in l
#we append x to l and return l when x is not in l
l if x in l else (l.append(x) or l)

我们在哪里:

  1. x 附加到l 并在x 不在l 中时返回l。感谢or 语句,.append 被评估,l 被返回。
  2. xl 中时返回l untouched

【讨论】:

  • 我试图理解为什么unique = [used.append(x) for x in mylist if x not in used] 不起作用。为什么我们必须将and (used.append(x) or True) 放在列表推导的末尾?
  • @Monica 基本上是因为used.append(x)x 添加到used 但这个函数的返回值是None,所以如果我们跳过or True 部分,我们会得到:@ 987654405@ 将始终评估为 False 并且 unique 列表将保持为空。
  • 别担心,没有愚蠢的问题,只有愚蠢的答案 :) 我更新了我的答案,试图更好地解释它的工作原理,希望我说清楚,你现在可以理解了。
  • 使用集合更快:timeit.timeit('[x for x in mylist if x not in used and not used.add(x)]', setup='used = set();'+setup)
  • 另一个值得一提和工作的选项,因为 Python 3.7 使用 dict,因为它保持了键的顺序,但也消除了重复:list(dict.fromkeys(mylist)) 在时间方面它定位为第三。
【解决方案2】:

删除重复项的选项可能包括以下通用数据结构:

这里是关于在 Python 中快速获取其中任何一个的总结。

给定

from collections import OrderedDict


seq = [u"nowplaying", u"PBS", u"PBS", u"nowplaying", u"job", u"debate", u"thenandnow"]

代码

选项 1 - 一组(无序):

list(set(seq))
# ['thenandnow', 'PBS', 'debate', 'job', 'nowplaying']

选项 2 - Python 没有有序集合,但这里有 some ways 来模仿一个(插入有序):

list(OrderedDict.fromkeys(seq))
# ['nowplaying', 'PBS', 'job', 'debate', 'thenandnow']

list(dict.fromkeys(seq))                               # py36
# ['nowplaying', 'PBS', 'job', 'debate', 'thenandnow']

如果使用 Python 3.6+,建议使用最后一个选项。在post 中查看更多详细信息。

注意:列出的元素必须是hashable。请参阅blog post 中有关后一个示例的详细信息。此外,请参阅 R. Hettinger 的 post 关于相同技术;保留顺序的字典是从他的早期实现之一扩展而来的。另请参阅total ordering

【讨论】:

  • @Henry Henrinson 我很感激你表达了你对这个答案投反对票的理由。但是,您的意见和声称“Python 3.6 解决方案不保留顺序”不符合参考标准。需要明确的是,在 Python 3.6 中,字典 preserve insertion order 在 CPython 实现中。它是 Python 3.7+ 中的语言特性。此外,请参阅正在进行的blog post,该方法当时声称是 Python 3.6 中排序最快的选项。
【解决方案3】:

一个 Python 列表:

>>> a = ['a', 'b', 'c', 'd', 'b']

要获得独特的项目,只需将其转换为集合(如果需要,您可以再次转换回列表):

>>> b = set(a)
>>> print(b)
{'b', 'c', 'd', 'a'}

【讨论】:

  • 很好,所以a = list(set(a)) 得到了独特的物品。
  • Brian, set(a) 足以“获得独特的物品”。如果您出于某种原因特别需要一个列表,则只需要构建另一个列表。
  • 注意结果是无序的。
【解决方案4】:

你的输出变量是什么类型的?

Python sets 是您所需要的。像这样声明输出:

output = set()  # initialize an empty set

您已准备好使用output.add(elem) 添加元素并确保它们是独一无二的。

警告:集合不保留列表的原始顺序。

【讨论】:

    【解决方案5】:

    首先正确声明您的列表,用逗号分隔。您可以通过将列表转换为集合来获取唯一值。

    mylist = ['nowplaying', 'PBS', 'PBS', 'nowplaying', 'job', 'debate', 'thenandnow']
    myset = set(mylist)
    print(myset)
    

    如果您将其进一步用作列表,则应通过以下操作将其转换回列表:

    mynewlist = list(myset)
    

    另一种可能更快的可能性是从一开始就使用集合,而不是列表。那么你的代码应该是:

    output = set()
    for x in trends:
        output.add(x)
    print(output)
    

    正如已经指出的那样,集合不保持原始顺序。如果需要,您应该寻找 ordered set 实现(请参阅 this question 了解更多信息)。

    【讨论】:

    • 如果您需要维护设置的顺序,PyPI 上还有一个库:pypi.python.org/pypi/ordered-set
    • 为什么列表有 '.append' 而集合有 '.add' ??
    • "append" 表示添加到末尾,这对列表来说是准确且有意义的,但集合没有排序的概念,因此没有开始或结束,因此“添加”对它们更有意义.
    • 'sets' 模块已被弃用,是的。因此,您不必“导入集合”即可获得该功能。如果您看到 import sets; output = sets.Set() 已弃用此答案使用内置的“设置”类 docs.python.org/2/library/stdtypes.html#set
    • 如果列表的值不可散列(例如,集合或列表),这将不起作用
    【解决方案6】:

    Set 是 un-orderedunique 元素的集合。因此,您可以使用如下设置来获取唯一列表:

    unique_list = list(set([u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']))
    

    【讨论】:

    • 虽然此代码可能会回答问题,但提供有关 why 和/或 如何 回答问题的额外上下文将显着改善其长期价值。请edit你的答案添加一些解释。
    • "集合是有序且唯一元素的集合。"不幸的是,没有;集合未按照上述答案中的说明进行排序。
    【解决方案7】:

    set 可以帮助您从列表中过滤掉重复的元素。它适用于strinttuple 元素,但如果您的列表包含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
    

    【讨论】:

      【解决方案8】:

      使用 Python 字典的基本属性:

      inp=[u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
      d={i for i in inp}
      print d
      

      输出将是:

      set([u'nowplaying', u'job', u'debate', u'PBS', u'thenandnow'])
      

      【讨论】:

      • 而且,从动态值来看?
      • @e-info128 非常相似,将它们放入set
      • 这是set,而不是dict
      【解决方案9】:

      使用 set 对列表进行去重,作为列表返回

      def get_unique_list(lst):
              if isinstance(lst,list):
                  return list(set(lst))
      

      【讨论】:

      • 这种方法会改变列表中元素的顺序,这可能是不受欢迎的行为
      【解决方案10】:

      维护秩序:

      # 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
      

      顺序无关紧要:

      # fastest-est -> --- 0.0035 seconds ---
      list(set(array))
      

      【讨论】:

      • 这对于大型列表具有糟糕的性能 (O(n^2)),并且既不比 list(set(array)) 更简单也更容易阅读。唯一的好处是保持秩序,这是不被要求的。
      • 这对于您想要保持秩序并且不关心速度的简单脚本非常有用。
      • @JeffCharter- 增加了一个维护秩序并且速度更快的 :)
      • 非常感谢您也抽出时间来破解时间戳
      【解决方案11】:

      从列表中获取唯一元素

      mylist = [1,2,3,4,5,6,6,7,7,8,8,9,9,10]
      

      使用集合中的简单逻辑 - 集合是唯一的项目列表

      mylist=list(set(mylist))
      
      In [0]: mylist
      Out[0]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      

      使用简单的逻辑

      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]
      

      使用弹出方法 ->pop 删除最后一个或索引的项目并将其显示给用户。 video

      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]
      

      使用 Numpy

      import numpy as np
      np.unique(mylist)
      
      In [0]: mylist
      Out[0]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      

      Reference

      【讨论】:

      • 这个答案值得更多升级:对于您想要检查 value 唯一性而不是 identity 唯一性的不可散列类型,简单的逻辑是正确的 - 这意味着它总的来说更正确。
      【解决方案12】:

      除了前面的答案,说你可以将你的列表转换为集合,你也可以这样做

      mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenadnow']
      mylist = [i for i in set(mylist)]
      

      输出将是

      [u'nowplaying', u'job', u'debate', u'PBS', u'thenadnow']
      

      虽然订单不会被保留。

      另一个更简单的答案可能是(不使用集合)

      >>> t = [v for i,v in enumerate(mylist) if mylist.index(v) == i]
      [u'nowplaying', u'PBS', u'job', u'debate', u'thenadnow']
      

      【讨论】:

        【解决方案13】:

        我检查内容的唯一性但保留原始顺序的解决方案:

        def getUnique(self):
            notunique = self.readLines()
            unique = []
            for line in notunique: # Loop over content
                append = True # Will be set to false if line matches existing line
                for existing in unique:
                    if line == existing: # Line exists ? do not append and go to the next line
                        append = False
                        break # Already know file is unique, break loop
                if append: unique.append(line) # Line not found? add to list
            return unique
        

        编辑: 通过使用字典键检查是否存在而不是为每一行执行整个文件循环可能会更有效,我不会将我的解决方案用于大型集合。

        【讨论】:

          【解决方案14】:

          我很惊讶到目前为止没有人给出直接的保持秩序的答案:

          def unique(sequence):
              """Generate unique items from sequence in the order of first occurrence."""
              seen = set()
              for value in sequence:
                  if value in seen:
                      continue
          
                  seen.add(value)
          
                  yield value
          

          它将生成值,因此它不仅仅适用于列表,例如unique(range(10))。要获取列表,只需致电list(unique(sequence)),如下所示:

          >>> list(unique([u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']))
          [u'nowplaying', u'PBS', u'job', u'debate', u'thenandnow']
          

          它要求每个项目都是可散列的,而不仅仅是可比较的,但 Python 中的大多数东西都是 O(n) 而不是 O(n^2),所以对于长列表也可以正常工作。

          【讨论】:

            【解决方案15】:

            您可以使用集合。为了清楚起见,我正在解释列表和集合之间的区别。 集合是唯一元素的无序集合。列表是元素的有序集合。 所以,

                unicode_list=[u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job',u'debate', u'thenandnow']
                list_unique=list(set(unicode_list))
                print list_unique
            [u'nowplaying', u'job', u'debate', u'PBS', u'thenandnow']
            

            但是:不要使用 list/set 来命名变量。它会导致错误: EX:而不是使用 list 而不是上面的 unicode_list 。

            list=[u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job',u'debate', u'thenandnow']
                    list_unique=list(set(list))
                    print list_unique
                list_unique=list(set(list))
            TypeError: 'list' object is not callable
            

            【讨论】:

              【解决方案16】:

              如果您想从列表中获取唯一元素并保持其原始顺序,那么您可以使用 Python 标准库中的 OrderedDict 数据结构:

              from collections import OrderedDict
              
              def keep_unique(elements):
                  return list(OrderedDict.fromkeys(elements).keys())
              
              elements = [2, 1, 4, 2, 1, 1, 5, 3, 1, 1]
              required_output = [2, 1, 4, 5, 3]
              
              assert keep_unique(elements) == required_output
              

              事实上,如果你使用 Python ≥ 3.6,你可以使用普通的dict

              def keep_unique(elements):
                  return list(dict.fromkeys(elements).keys())
              

              在引入 dicts 的“紧凑”表示后,这成为可能。看看here。虽然这“考虑了一个实现细节,不应依赖”。

              【讨论】:

              • 我真的很想把最后一点开车回家。让 dict 在内部保持插入顺序是 CPython 的一个实现细节,并且不能保证它可以在另一个 Python 引擎(如 PyPy 或 IronPython)上工作,并且它可以在未来的版本中更改而不会破坏向后兼容性。所以请不要在任何生产就绪的代码中依赖这种行为。
              • @BerislavLopac,我完全同意。它可能会发生变化,并且不遵循“可读性计数”规则。但它对于一次性脚本和 REPL 会话仍然很方便。
              • 事实上——纠正我自己的观点——从 Python 3.7 开始,有序的字典实际上是一种语言特性,而不是实现的怪癖。在stackoverflow.com/a/39980744/122033查看答案
              【解决方案17】:

              要从您的列表中获取唯一值,请使用以下代码:

              trends = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
              output = set(trends)
              output = list(output)
              

              重要提示: 如果列表中的任何项目不是hashablemutable 类型,例如listdict),则上述方法将不起作用。

              trends = [{'super':u'nowplaying'}, u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
              output = set(trends)
              Traceback (most recent call last):
                File "<stdin>", line 1, in <module>
                TypeError: unhashable type: 'dict'
              

              这意味着您必须确保trends 列表始终只包含可散列项,否则您必须使用更复杂的代码:

              from copy import deepcopy
              
              try:
                  trends = [{'super':u'nowplaying'}, [u'PBS',], [u'PBS',], u'nowplaying', u'job', u'debate', u'thenandnow', {'super':u'nowplaying'}]
                  output = set(trends)
                  output = list(output)
              except TypeError:
                  trends_copy = deepcopy(trends)
                  while trends_copy:
                      trend = trends_copy.pop()
                      if trends_copy.count(trend) == 0:
                          output.append(trend)
              print output
              

              【讨论】:

                【解决方案18】:

                我知道这是一个老问题,但这是我独特的解决方案:类继承!:

                class UniqueList(list):
                    def appendunique(self,item):
                        if item not in self:
                            self.append(item)
                            return True
                        return False
                

                然后,如果您想将项目唯一地附加到列表中,您只需在 UniqueList 上调用 appendunique。因为它继承自一个列表,它基本上就像一个列表,所以你可以使用 index() 等函数。因为它返回 true 或 false,你可以找出追加成功(唯一项)还是失败(已经在列表)。

                要从列表中获取唯一的项目列表,请使用 for 循环将项目附加到 UniqueList(然后复制到列表中)。

                示例使用代码:

                unique = UniqueList()
                
                for each in [1,2,2,3,3,4]:
                    if unique.appendunique(each):
                        print 'Uniquely appended ' + str(each)
                    else:
                        print 'Already contains ' + str(each)
                

                打印:

                Uniquely appended 1
                Uniquely appended 2
                Already contains 2
                Uniquely appended 3
                Already contains 3
                Uniquely appended 4
                

                复制到列表:

                unique = UniqueList()
                
                for each in [1,2,2,3,3,4]:
                    unique.appendunique(each)
                
                newlist = unique[:]
                print newlist
                

                打印:

                [1, 2, 3, 4]
                

                【讨论】:

                  【解决方案19】:

                  作为奖励,Counter 是一种获取唯一值和每个值的计数的简单方法:

                  from collections import Counter
                  l = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
                  c = Counter(l)
                  

                  【讨论】:

                    【解决方案20】:

                    为了与我将使用的类型保持一致:

                    mylist = list(set(mylist))
                    

                    【讨论】:

                    • 请注意,结果是无序的。
                    • @Ninjakannon 您的代码将按字母顺序对列表进行排序。这不一定是原始列表的顺序。
                    • 注意在 python 3 中一个简洁的方法是mylist = [*{*mylist}]。这是一个*arg-style 集合扩展,后跟一个*arg-style list-expansion。
                    • @LukeDavis 对我来说是最佳答案,sorted([*{*c}])sorted(list(set(c))) 快 25%(用timeit.repeat 测量,数字=100000)
                    • 注:如果列表包含不可散列的元素(例如,本身是集合、列表或散列的元素),则会失败。
                    【解决方案21】:
                    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
                    

                    【讨论】:

                    【解决方案22】:

                    set - 独特元素的无序集合。可以将元素列表传递给 set 的构造函数。因此,传递具有重复元素的列表,我们设置唯一元素并将其转换回列表,然后获取具有唯一元素的列表。关于性能和内存开销,我无话可说,但我希望,对于小列表来说,这并不是那么重要。

                    list(set(my_not_unique_list))
                    

                    简单而简短。

                    【讨论】:

                    • 您能否为您的 OP 代码添加一些解释?
                    • 我试过你的答案,这是一个很好的答案,但有一个解释它会变成一个很好的答案:)
                    • set - 独特元素的无序集合。可以将元素列表传递给 set 的构造函数。因此,传递具有重复元素的列表,我们设置唯一元素并将其转换回列表,然后获取具有唯一元素的列表。关于性能和内存开销,我无话可说,但我希望,对于小列表来说,这并不是那么重要。
                    【解决方案23】:

                    如果您在代码中使用 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')
                    

                    (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
                    

                    如果你真的想要一个普通的 python 列表,你可以随时调用 list()。

                    但是,从上面的代码片段可以看出,结果是自动排序的。如果需要保留列表顺序,请查看numpy unique without sort

                    【讨论】:

                      【解决方案24】:

                      仅使用列表压缩的相同顺序唯一列表。

                      > 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]
                      

                      enumerates 将索引 i 和元素 e 作为 tuple

                      my_list.index 返回e 的第一个索引。如果第一个索引不是i,则当前迭代的e 不是列表中的第一个e

                      编辑

                      我应该指出,从性能角度来看,这不是一个好方法。这只是一种仅使用列表压缩来实现它的方法。

                      【讨论】:

                        【解决方案25】:

                        对于长数组

                        s = np.empty(len(var))
                        
                        s[:] = np.nan
                        
                        for  x in  set(var):
                        
                            x_positions = np.where(var==x)
                        
                            s[x_positions[0][0]]=x
                        
                        
                        sorted_var=s[~np.isnan(s)]
                        

                        【讨论】:

                          【解决方案26】:

                          使用以下函数:

                          def uniquefy_list(input_list):
                          """
                          This function  takes a list as input and return a list containing only unique elements from the input list
                          
                          """
                          output_list=[]
                          for elm123 in input_list:
                              in_both_lists=0
                              for elm234 in output_list:
                                  if elm123 == elm234:
                                      in_both_lists=1
                                      break
                              if in_both_lists == 0:
                                  output_list.append(elm123)
                          
                          return output_list
                          

                          【讨论】:

                            【解决方案27】:

                            试试这个函数,它和你的代码类似,但它是一个动态范围。

                            def unique(a):
                            
                                k=0
                                while k < len(a):
                                    if a[k] in a[k+1:]:
                                        a.pop(k)
                                    else:
                                        k=k+1
                            
                            
                            
                                return a
                            

                            【讨论】:

                              【解决方案28】:
                              def setlist(lst=[]):
                                 return list(set(lst))
                              

                              【讨论】:

                              • 尽量不要使用 [] 作为默认参数。每次都使用相同的实例,因此修改会影响下一次调用该函数。这里不是什么大问题,但仍然没有必要。
                              • @Trengot 没错。应该是 lst=None,如果 lst 是 None 则添加一行 lst = []
                              • @xis: 或者干脆lst or []
                              • 请注意,结果是无序的。
                              【解决方案29】:
                              1. 在代码的开头,只需将输出列表声明为空:output=[]
                              2. 您可以使用此代码trends=list(set(trends))代替您的代码

                              【讨论】:

                              • 请注意,结果是无序的。
                              【解决方案30】:

                              首先,您提供的示例不是有效列表。

                              example_list = [u'nowplaying',u'PBS', u'PBS', u'nowplaying', u'job', u'debate',u'thenandnow']
                              

                              假设如果上面是示例列表。然后,您可以使用以下配方作为 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
                              

                              【讨论】:

                              • seen_add = seen.add 的原因是什么?
                              • 它为每个元素保存一个属性查找。
                              • ifilterfalse(seen.__contains__, iterable) 的目的是什么?与for element not in seen:... 相比有什么好处吗?
                              猜你喜欢
                              • 2013-06-12
                              • 2021-06-06
                              • 1970-01-01
                              • 2019-04-22
                              • 1970-01-01
                              • 2013-08-14
                              • 2015-04-26
                              • 2010-11-26
                              • 1970-01-01
                              相关资源
                              最近更新 更多