简体   繁体   English

如何检查嵌套列表树的所有元素是否相同?

[英]How do I check if all the elements of a nested list tree are identical?

I am trying to create a function allsametree(tree) that takes a list, tree , as an input and returns TRUE or FALSE if all the elements of the list are numerically identical.我正在尝试创建一个函数allsametree(tree) ,它将列表tree作为输入,如果列表的所有元素在数字上相同,则返回 TRUE 或 FALSE。 So far, I have the following function:到目前为止,我有以下功能:

def allsametree(tree):
    if not type(tree) == list:
        return tree
    if type(tree) is list:
        final_lst = []
        for item in tree:
            final_lst.append(allsametree(item))
        return final_lst[1:] == final_lst[:-1]

While for the most part, this function works, it runs into an issue when evaluating allsametree([1, [[[[[2]]]]]])虽然在大多数情况下,此函数有效,但在评估allsametree([1, [[[[[2]]]]]])allsametree([1, [[[[[2]]]]]])问题

Any tips, or alternative ways you would approach this problem?任何提示或替代方法可以解决这个问题?

You can recursively convert the list to a set of items and return true if the length of the overall set is 1:您可以递归地将列表转换为一组项目,如果整个集合的长度为 1,则返回 true:

def allsametree(tree):
    def to_set(tree):
        if isinstance(tree, list):
            return {item for obj in tree for item in to_set(obj)}
        return {tree}
    return len(to_set(tree)) == 1

Another way to do it.另一种方法来做到这一点。 Split it into two operations a flatten and a check that all the values are the same.将其拆分为两个操作:展平和检查所有值是否相同。

The flatten will convert a nested iterable into one of a single dimension. flatten 会将嵌套的可迭代对象转换为单个维度之一。 So [1, [[[[[2]]]]]] becomes [1,2] .所以[1, [[[[[2]]]]]]变成[1,2]

Then read the first value and cycle through the rest to check they are the same as it.然后读取第一个值并循环遍历其余值以检查它们是否与它相同。

Here's the code这是代码

from collections.abc import Iterable

def flatten(iterable):
    for i in iterable:
        if isinstance(i, Iterable):
            yield from flatten(i)
        else:
            yield i


def allsametree(tree):
    flat = flatten(tree)
    iterator = iter(flat)
    try:
        first = next(iterator)
    except StopIteration:
        return True
    return all(first == rest for rest in iterator)

This will work for any iterable not just lists and because it uses lazy evaluation, it will stop when it finds two values that are not equal.这将适用于任何iterable不仅仅是列表,并且因为它使用惰性求值,当它发现两个不相等的值时它会停止。 This saves you from doing unnecessary work.这可以避免您做不必要的工作。 It also avoid instantiating temporary collections (lists, sets etc.) being constructed on each recursive call.它还避免实例化在每次递归调用时构造的临时集合(列表、集合等)。

Here's a few test inputs. 是一些测试输入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM