检查迭代器是否已排序

Zac*_*Zac 5 python iterator

我有一个迭代器it,我假设已经排序但我想提出异常,如果不是.

来自迭代器的数据不在内存中,所以我不想使用sorted()内置,因为AFAIK它将整个迭代器放在一个列表中.

我现在使用的解决方案是将迭代器包装在生成器函数中,如下所示:

def checkSorted(it):
  prev_v = it.next()
  yield prev_v
  for v in it:
    if v >= prev_v:
      yield v
      prev_v = v
    else:
      raise ValueError("Iterator is not sorted")
Run Code Online (Sandbox Code Playgroud)

所以我可以像这样使用它:

myconsumer(checkSorted(it))
Run Code Online (Sandbox Code Playgroud)

有人知道是否有更好的解决方案?

我知道我的解决方案有效但似乎很奇怪(至少对我而言)我自己编写一个模块来完成这样一个简单的任务.我正在寻找一个简单的单线或内置解决方案(如果存在)

Kas*_*mvd 2

作为替代方案,我建议使用itertools.izip_longestzip_longest在 python 3 中)创建一个包含连续对的生成器:

您可以使用tee第一个可迭代对象创建 2 个独立的迭代器。

from itertools import izip_longest,tee

def checkSorted(it):
  pre,it=tee(it)
  next(it)
  for i,j in izip_longest(pre,it):
    if j:
      if i >= j:         
        yield i
      else:
        raise ValueError("Iterator is not sorted")
    else :
        yield i
Run Code Online (Sandbox Code Playgroud)

演示:

it=iter([5,4,3,2,1])
print list(checkSorted(it))

[5, 4, 3, 2, 1]

it=iter([5,4,3,2,3])
print list(checkSorted(it))

Traceback (most recent call last):
  File "/home/bluebird/Desktop/ex2.py", line 19, in <module>
    print list(checkSorted(it))
  File "/home/bluebird/Desktop/ex2.py", line 10, in checkSorted
    raise ValueError("Iterator is not sorted")
ValueError: Iterator is not sorted
Run Code Online (Sandbox Code Playgroud)

注意:实际上我认为没有必要生成可迭代的值,因为你已经有了它们。因此,作为一种更优雅的方式,我建议在函数中使用生成器表达式all并返回 bool 值:

from itertools import izip,tee

def checkSorted(it):
  pre,it=tee(it)
  next(it)
  return all(i>=j for i,j in izip(pre,it))
Run Code Online (Sandbox Code Playgroud)

  • 最后一个解决方案不如原始解决方案那么好,因为 `tee` 内部存储了所有迭代器未消耗的任何元素。由于您消耗了所有“pre”和“it”,但没有消耗“main_it”,这基本上使“tee”存储所有元素 - 这正是OP试图避免的! (2认同)