【问题标题】:What is the Pythonic way to check if a list of strings is sorted or not?检查字符串列表是否已排序的 Pythonic 方法是什么?
【发布时间】:2021-10-16 22:24:08
【问题描述】:

我有一个字符串列表

my_string_list = ['Banana', 'Apple', 'Sorry']

如何检查此my_string_list 是否已排序?

一种明显的方法是对该列表进行排序并将其与原始列表进行比较。但我不想遍历整个原始列表来确定该列表未排序。

sorted_list_of_strings = sorted(my_string_list)
if my_string_list != sorted_list_of_strings:
    print(f'The list {my_string_list} is not sorted.')

我想知道是否有其他方法可以做到这一点?

【问题讨论】:

  • 为什么不sort 它并确定知道?
  • 我不想为了检查它是否已排序而对一百万个项目的列表进行排序!
  • 提问时,细节很重要。在这个问题中,您省略了多个,这将被认为与提供有意义的答案相关。
  • 这能回答你的问题吗? How do I check if a list is sorted?
  • 不完全是。这会遍历整个列表以得出结论。另外,我已经编辑了我的问题。

标签: python-3.x string list sorting


【解决方案1】:

通常,我会使用您的解决方案 (if x == sorted(x):) 并接受费用;它很容易编写,如果它不是一个热代码路径,那么如果你这样做效率低下也没什么关系(对于已经排序的情况,由于 Python 的 TimSort,它大约是O(n),所以你只为“未排序”情况支付O(n log n)一般排序费用)。当您需要处理反向排序、键控排序等时,它也很容易自定义,同时保持易于编写和易于检查验证。

如果您想要一个使用 Python 内置函数的更高效的解决方案,您可以执行以下操作(在文件顶部使用 from operator import le):

if all(map(le, my_string_list, my_string_list[1:])):

将每个元素与下一个元素进行比较,在第一个不匹配时返回False,如果它们都小于或等于下一个元素,则返回True。如果您担心使用普通切片构建临时 list 的成本(计算或内存成本),请将 my_string_list[1:] 替换为 itertools.islice(my_string_list, 1, None)。

【讨论】:

  • 这不是很有效,因为my_string_list[1:] 是一个副本。最好成对迭代元素,或者迭代range(len(my_string_list))和索引。
  • @wim: 最好使用itertools.islice 对其进行优化,或者手动创建一个迭代器并将其推进一次,然后使用该迭代器作为第二个参数,但这只是一个额外的O(n) 步骤正常切片,然后是相对便宜的O(n) 步骤。如有必要,islice(my_string_list, 1, None) 将替换 my_string_list[1:] 以使其保持单线,但除非您经常这样做,否则这是过早的优化。
  • 我不是在谈论时间复杂性,我是在谈论内存效率。
  • @wim:当然。但同样,在大多数情况下过早优化。如果您的list 长度为 10,000 个元素,则增量成本是临时消耗 80 KB(在 64 位系统上);几乎不重要(它总是一个浅拷贝,所以存储的对象的大小无关紧要)。 islice 避免了这个问题,但我会跳过它,除非我知道它是最热门的代码路径和/或输入会很大。为了清楚起见,我在答案中添加了注释。
  • 如果您使用生成器表达式而不是 map,您的代码将很容易通过检查来修改和验证。
猜你喜欢
  • 2011-04-14
  • 2017-01-01
  • 2010-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
相关资源
最近更新 更多