从Python列表中获取前n个唯一元素

我有一个python列表,其中元素可以重复。

>>> a = [1,2,2,3,3,4,5,6]

我想从列表中获得第一个n个独特元素。因此,在这种情况下,如果我想要前5个唯一元素,它们将是:

[1,2,3,4,5]

我想出了一个使用生成器的解决方案:

def iterate(itr, upper=5):

count = 0

for index, element in enumerate(itr):

if index==0:

count += 1

yield element

elif element not in itr[:index] and count

count += 1

yield element

正在使用:

>>> i = iterate(a, 5)

>>> [e for e in i]

[1,2,3,4,5]

我怀疑这是否是最佳解决方案。 有没有一种我可以实现的替代策略,可以用更加Python化和高效的方式编写它方式?

12个解决方案

47 votes

如果您有足够的set( {1,2,3,4,5,6}),我将使用5001*O(1)记住所看到的内容并从生成器返回:

a = [1,2,2,3,3,4,5,6]

def get_unique_N(iterable, N):

"""Yields (in order) the first N unique elements of iterable.

Might yield less if data too short."""

seen = set()

for e in iterable:

if e in seen:

continue

seen.add(e)

yield e

if len(seen) == N:

return

k = get_unique_N([1,2,2,3,3,4,5,6], 4)

print(list(k))

输出:

[1,2,3,4]

根据PEP-479,您应该从生成器中获取5001*O(1),而不是从set( {1,2,3,4,5,6})生成器-感谢@khelwood&@iBug的评论-一个永远不会学到的东西。

使用3.6时,您会收到不赞成使用的警告,使用3.7时,它将给出RuntimeErrors:Transition Plan,如果仍在使用5001*O(1)

您使用5001*O(1)的解决方案将使用set( {1,2,3,4,5,6})查找-将k作为切片的长度-使用一组将其减少为O(1)查找,但由于必须同时保留该组,因此会使用更多内存。 这是速度与内存之间的权衡-更好的是应用程序/数据依赖。

考虑5001*O(1)和set( {1,2,3,4,5,6}):

对于6个唯一身份(在更长的列表中):

您将查找5001*O(1)

我将有5001*O(1)查找和set( {1,2,3,4,5,6})的内存

Patrick Artner answered 2020-06-30T05:02:27Z

23 votes

您可以改编流行的more_itertools.unique_everseen unique_everseen食谱:

def unique_everseen_limit(iterable, limit=5):

seen = set()

seen_add = seen.add

for element in iterable:

if element not in seen:

seen_add(element)

yield element

if len(seen) == limit:

break

a = [1,2,2,3,3,4,5,6]

res = list(unique_everseen_limit(a)) # [1, 2, 3, 4, 5]

或者,按照@Chris_Rands的建议,您可以使用more_itertools.unique_everseen从非限制生成器中提取固定数量的值:

from itertools import islice

def unique_everseen(iterable):

seen = set()

seen_add = seen.add

for element in iterable:

if element not in seen:

seen_add(element)

yield element

res = list(islice(unique_everseen(a), 5)) # [1, 2, 3, 4, 5]

请注意,可通过more_itertools.unique_everseen或toolz.unique在第三方库中获得more_itertools.unique_everseen配方,因此您可以使用:

from itertools import islice

from more_itertools import unique_everseen

from toolz import unique

res = list(islice(unique_everseen(a), 5)) # [1, 2, 3, 4, 5]

res = list(islice(unique(a), 5)) # [1, 2, 3, 4, 5]

jpp answered 2020-06-30T05:02:56Z

9 votes

如果您的对象是可哈希对象(nub是可哈希对象),则可以使用nub类的nub方法(或从Python3.7开始的普通dict,因为它们已正式订购)来编写实用程序函数,例如

from collections import OrderedDict

def nub(iterable):

"""Returns unique elements preserving order."""

return OrderedDict.fromkeys(iterable).keys()

然后nub的实现可以简化为

from itertools import islice

def iterate(itr, upper=5):

return islice(nub(itr), upper)

或者如果您始终希望将nub作为输出

def iterate(itr, upper=5):

return list(nub(itr))[:upper]

改进措施

正如@Chris_Rands提到的那样,此解决方案遍历整个集合,我们可以通过像其他人已经做过的那样以生成器的形式编写nub实用程序来改进此解决方案:

def nub(iterable):

seen = set()

add_seen = seen.add

for element in iterable:

if element in seen:

continue

yield element

add_seen(element)

Azat Ibrakov answered 2020-06-30T05:03:34Z

6 votes

您可以使用OrderedDict,也可以使用Python 3.7之后的普通dict,因为它们是为保留插入顺序而实现的。 请注意,这不适用于集合。

N = 3

a = [1, 2, 2, 3, 3, 3, 4]

d = {x: True for x in a}

list(d.keys())[:N]

Jindra Helcl answered 2020-06-30T05:03:54Z

6 votes

这是使用itertools.takewhile()的Pythonic方法:

In [95]: from itertools import takewhile

In [96]: seen = set()

In [97]: set(takewhile(lambda x: seen.add(x) or len(seen) <= 4, a))

Out[97]: {1, 2, 3, 4}

Kasramvd answered 2020-06-30T05:04:14Z

5 votes

这个问题确实有惊人的答案,它们快速,紧凑,出色! 我在此处放置此代码的原因是,我相信在很多情况下,您不必关心1微秒的时间松散,也不希望在代码中使用其他库来一次性解决一个简单的任务。

a = [1,2,2,3,3,4,5,6]

res = []

for x in a:

if x not in res: # yes, not optimal, but doesnt need additional dict

res.append(x)

if len(res) == 5:

break

print(res)

grapes answered 2020-06-30T05:04:34Z

4 votes

将set与sorted+ key结合使用

sorted(set(a), key=list(a).index)[:5]

Out[136]: [1, 2, 3, 4, 5]

WeNYoBen answered 2020-06-30T05:04:54Z

4 votes

假设元素的排列顺序如图所示,这是一个有乐趣的itertools中的islice函数的机会:

from itertools import groupby, islice

def first_unique(data, upper):

return islice((key for (key, _) in groupby(data)), 0, upper)

a = [1, 2, 2, 3, 3, 4, 5, 6]

print(list(first_unique(a, 5)))

更新为使用islice代替每个@ juanpa.arrivillaga的enumerate。 您甚至不需要set即可跟踪重复项。

cdlane answered 2020-06-30T05:05:19Z

4 votes

给定

import itertools as it

a = [1, 2, 2, 3, 3, 4, 5, 6]

一个简单的列表理解(类似于@cdlane的答案)。

[k for k, _ in it.groupby(a)][:5]

# [1, 2, 3, 4, 5]

或者,在Python 3.6+中:

list(dict.fromkeys(a))[:5]

# [1, 2, 3, 4, 5]

pylang answered 2020-06-30T05:05:51Z

1 votes

为什么不使用这样的东西?

>>> a = [1, 2, 2, 3, 3, 4, 5, 6]

>>> list(set(a))[:5]

[1, 2, 3, 4, 5]

Александр Трубилин answered 2020-06-30T05:06:11Z

0 votes

示例列表:

a = [1, 2, 2, 3, 3, 4, 5, 6]

函数返回列表中所需的全部或唯一项的计数

第一个参数-要使用的列表,第二个参数(可选)-唯一项的计数(默认情况下-无-表示将返回所有唯一元素)

def unique_elements(lst, number_of_elements=None):

return list(dict.fromkeys(lst))[:number_of_elements]

这是它如何工作的示例。 列表名称为“ a”,我们需要获取2个唯一元素:

print(unique_elements(a, 2))

输出:

Quanti Monati answered 2020-06-30T05:06:49Z

0 votes

a = [1,2,2,3,3,4,5,6]

from collections import defaultdict

def function(lis,n):

dic = defaultdict(int)

sol=set()

for i in lis:

try:

if dic[i]:

pass

else:

sol.add(i)

dic[i]=1

if len(sol)>=n:

break

except KeyError:

pass

return list(sol)

print(function(a,3))

输出

[1, 2, 3]

temmo answered 2020-06-30T05:07:09Z

python取列表前几个元素_从Python列表中获取前n个唯一元素相关推荐

  1. 如何从JavaScript数组中获取多个随机唯一元素?

    The JavaScript is a very versatile language and it has a function almost everything that you want. J ...

  2. jquery获取元素的索引_如何在jQuery中获取具有特定索引的元素

    jquery获取元素的索引 In this post, we are going to discuss how to get an element with a specific index. jQu ...

  3. jquery 获取同级元素_如何在jQuery中获取元素的同级

    jquery 获取同级元素 In this post, we will discuss how to get the siblings of an HTML element in jQuery. jQ ...

  4. vector删除第i个元素_[LeetCode] 215. 数组中的第K个最大元素

    题目链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array/) 题目描述: 在未排序的数组中找到第 k 个最大的元素.请 ...

  5. python中元组怎么存放元素_关于python列表和元组的基本操作

    一.列表 列表是python中最常出现的一种数据存储形式,掌握列表的基本操作可以快速而有效的提高我们的代码书写效率.列表中存放的数据有如下基本操作:如增.删.改.查,掌握了这四个操作,就基本掌握了列表 ...

  6. python 无序列表中第k大元素_查询无序列表中第K小元素

    当需要在无需列表中寻找第k小的元素时,一个显然的方法是将所有数据进行排序,然后检索k个元素.这种方法的运行时间为O(n log(n)). 无序列表调用分区函数将自身分解成两个子表,其长度为i和n-i. ...

  7. python list去重并删除某些元素_使用Python实现list(列表)中的重复元素删除,例如: X= [1,1,2,a,a,[1,2,3]] 去重后:X= 「1,2,a,[1,2...

    题目要求的实质是列表内部元素的去重,有两种思路:第一种,删除的思路,判断列表中的元素是否出现重复,如果有重复,删除重复出现的元素直到剩下最后一个:第二种,添加的思路,新建空列表,将新列表中不包含.原列 ...

  8. python list查找元素_使用python list 查找所有匹配元素的位置实例

    使用python list 查找所有匹配元素的位置实例 如下所示: import re word = "test" s = "test abcdas test 1234 ...

  9. python将对象放入列表根据某个属性排序_关于python:如何根据对象的属性对对象列表进行排序?...

    我有一个python对象列表,我想按对象本身的属性排序.列表如下: >>> ut [, , , , , , ...] 每个对象都有一个计数: >>> ut[1].c ...

  10. python里面列表可以同时删除吗_在python中从列表中删除项,同时对其进行迭代

    本问题已经有最佳答案,请猛点这里访问. 我正在为锦标赛应用程序编写循环算法. 当玩家数量为奇数时,我将'DELETE'添加到玩家列表中,但稍后,当我想从包含'DELETE'的日程表列表中删除所有项目时 ...

最新文章

  1. python tk 持续请求接口获取数据_tk数据获得的问题!!
  2. qchart 坐标轴设置_实战PyQt5: 156-QChart图表之更换图表主题
  3. 上传图片---SpringMVC学习笔记(十一)
  4. beanutil 批量copy_BeanUtils.copyProperties 需要getset方法支持
  5. Javascript设计模式(二)工厂模式
  6. Android ------ 开源的Modnet算法实现抠图和更换背景
  7. IDEA 热部署插件 JRebel 激活
  8. windows 定时杀掉进程
  9. hpe 服务器 稳定性6,将NAA ID与运行ESXi 6.7的HPE服务器上的物理驱动器托架位置相关联...
  10. linux 如何通过进程号找到文件路径
  11. Tunnello安装指南
  12. C++大作业--班级同学信息管理系统
  13. 关于 Facebook的 SWE_NG_GCR-SEAsia
  14. 端口波特率有专门测试软件,波特率检查工具
  15. Asky极简教程:零基础1小时学编程,已更新前8节
  16. 基于Bert的智能对话机器人
  17. 阻塞IO与非阻塞IO(NIO)
  18. java阿里云邮件推送接口API使用
  19. Spark SQL 工作流程源码解析(四)optimization 阶段(基于 Spark 3.3.0)
  20. linux 时钟及UTC CST NTP NTPD服务

热门文章

  1. 软件需求分析(补发)
  2. Nginx配置SSL证书部署HTTPS网站
  3. 文件与文件系统的压缩与打包
  4. WCF集成COM+应用程序遇到的问题
  5. [导入]在windows下建立的自己cvsnt服务器
  6. 在Spring IoC中,依赖注入和依赖查找的数据来源区别
  7. springboot整合rabbitmq之消息的确认机制
  8. 一个简单的完全信息动态博弈的解答
  9. CentOS中文乱码问题
  10. idea提交本地项目到git