检查列表的大多数Python方法归结为一个值

问题描述 投票:0回答:3

我希望函数check检查给定的list在给定的函数reduce_function下是否减小(精确到)。 (一个常见的示例可能是检查列表列表是否仅包含相等长度的子列表。)

我至少看到以下三种方法来实现这一目标。对于他们每个人,我都会看到一些优点和缺点。在我看来,它们看起来都不是很可读。您能否给我详细介绍一下:

哪个将被认为是最易读和最“ pythonic”的?

1。测量一组缩减值的长度。

这似乎最易读,但是需要reduce_function返回可哈希的值:

def check(lst):
    return len(set(map(reduce_function, lst))) == 1

2。计算组数

def check(lst):
    return len(list(itertools.groupby(lst, key=reduce_function)) == 1

3。与第一个元素进行比较时使用all

这需要一个附加的or语句(可以用if-else语句代替)以覆盖lst为空的情况。

def check(lst):
    return not lst or all([reduce_function(el) == reduce_function(lst[0]) for el in lst])
python list itertools python-collections
3个回答
1
投票

这可能是基于观点的,但是也有客观的理由支持或反对不同的选择。在这里,我将重点介绍第一个和第三个。

第一种方法转换为set并测试其长度,恕我直言是最干净的,但是它有O(n)个额外的空间要求(在最坏的情况下,所有元素都not

相同)。它也适用于任何迭代,而第三个仅在lst实际上是list时有效。 以当前形式由于[...]中的列表理解all,第三种方法也具有O(n)空间复杂度(在all情况下);您可以改用生成器表达式。此外,针对每个其他元素重新计算reduce_function(lst[0])。最后,not lst or是冗余的,因为空列表的allTrue

此外,请注意,如果要测试列表是否“简化为” 至多

一个值,如not lst or所暗示,则应检查len(...) <= 1的前两种方法。

[我没有测试,但是我认为这应该起作用,并且a)使用不可散列reduce_function,b)是O(1)空间复杂度,c)使用列表或可迭代变量,并且d)尊重空列表角落案例:

def check(lst):
    return sum(1 for _ in itertools.groupby(lst, key=reduce_function)) <= 1

尽管,即使已经明确存在多个不同的值,它仍将对整个reduce_function求值lst


0
投票

我喜欢所有3个选项,尽管第三个选项不必是列表理解,只需取下方括号即可。


0
投票

如果要检查是否可以将所有值都减小为相同的值,则无需遍历整个列表。一旦发现一个不等于列表中第一个值的值,就可以停止。会更有效:

© www.soinside.com 2019 - 2024. All rights reserved.