【问题标题】:Python Check If List Is a Mathematical Set FastPython检查列表是否是一个快速的数学集
【发布时间】:2015-10-14 22:26:51
【问题描述】:

在python中检查列表是否是数学集的最快\最pythonic的方法是什么?

我知道以下作品:

ListInstance = [1,2,3,4,5,6]
ListIsMathSet = (len(set(ListInstance)) == len(ListInstance) )

有没有更好/更快的方法来检查这个?

【问题讨论】:

  • 我不认为你可以做得更好,除非你可以对输入列表做出一些保证......例如如果已排序。
  • 你有什么问题吗?是瓶颈吗?当你的变量名不是 Pythonic 时,为什么还要担心代码是 Pythonic?
  • 除非您正在处理如此大的数据集,以至于散列它们的开销变得令人望而却步,否则我会使用它。由于您已经编写了它,因此与其他方法相比,它的开发时间为零。
  • @jonrsharpe 变量名的大写方式真的有很大的不同吗?
  • 他们可以孤立地做他们喜欢做的事,但如果你在没有充分理由的情况下与其他人分享你的代码PEP-8

标签: python list set big-o isinstance


【解决方案1】:

通常不会更快,但如果值不可散列但它们是可比较的,特别是如果它们已经排序,你可以懒惰地确定是否有任何元素是非唯一的:

def is_unique(items, key=None):
    for k, g in itertools.groupby(sorted(items, key=key), key=key):
        if len(list(itertools.islice(g, 2))) > 1:
            return False
    return True

这将在检测到第一个重复项后立即停止,并且只进行必要的检查,这可能运行得更快(尤其是在“输入已排序”的情况下)。可以使用set 进行类似的基于早期输出的方法,方法是在快速违反唯一性的情况下进行迭代以最小化散列和存储的元素数量(改编自@987654324 中的unique_everseen 配方@):

def is_unique(iterable):
    seen = set()
    seen_add = seen.add
    for element in iterable:
        if element in seen:
            return False
        seen_add(element)
    return True

注意:在少数可散列输入的典型情况下,上述解决方案都不是更好的,其中唯一性很常见(或者至少在输入集的早期没有违反)。您提供的简单解决方案简洁明了,并且在 CPython 的 C 层执行大部分工作,因此与执行大量 Python 代码的方法相比,它的固定开销要低得多。但它们可能对于大型输入、已排序的输入和/或唯一性不常见的输入很有用(因此早期输出行为可以为您节省一些工作)。

【讨论】:

  • 注意:基于heapq 的基于sorted 的方法有一种替代方法,可以避免在输入尚未排序的情况下预先通过O(n log n) 工作,只需支付@ 987654329@ heapq.heapify 的初始成本,然后一次弹出值(O(log n) 每次弹出)并将弹出的值与 theheap[0] 进行比较以查找重复项。不过,这很少值得。 sorted 比使用 heapq 手动实现惰性排序要快得多,只有当您通常会在输入的第一个小部分(IIRC,大约六分之一?)中找到非唯一元素时才值得。跨度>
  • 我没有编辑您的答案的声誉:我基本上看到如果您开始的列表实例已排序,那么是的,您可以做得更好。您遍历事物,并检查两个相邻元素是否相等。一个迭代的邻居相等检查方法应该在一个排序列表上花费 N 时间。
  • @DAdams:正确。 Python 的 TimSort 算法的本质是对已经排序的列表进行排序与​​ N 工作成正比。如果您知道它已排序,则不再排序会快一点,但只是一点点。
猜你喜欢
  • 2013-12-12
  • 2012-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多