我想比较两个嵌套结构,例如比较[[[1],[2],[3]],[2],3]
和[1,'a',[[[1]],['abc','d']]]
。怎么办?
答案 0 :(得分:3)
从您的评论看来,列表中元素的类型和数量似乎都不重要,而列表本身的“嵌套结构”似乎都不重要。因此,您可以从列表中递归地删除不是另一个嵌套列表的所有内容,然后比较剩下的内容。
def purge(lst):
return [purge(x) for x in lst if isinstance(x, list)]
a = [[[1],[2],[3]],[2],3]
b = [1,'a',[[[1]],['abc','d']]]
purge(a)
# [[[], [], []], []]
purge(b)
# [[[[]], []]]
purge(a) == purge(b)
# False
随意将其扩展到其他结构,例如dict
和set
。
如果类型确实很重要,但不重要,则可以使用此变体,它将保留每个列表项的type
,但折叠相同的连续条目(请注意,它也折叠[7],[8],[9]
到[int]
(第一个版本除外):
import itertools
def purge2(lst):
tmp = [purge2(x) if isinstance(x, list) else type(x).__name__ for x in lst]
return [k for k, g in itertools.groupby(tmp)]
c = [[[1,2,3],["a","b"],4,[5,6]],[7],[8],[9]]
purge2(c)
# [[['int'], ['str'], 'int', ['int']], ['int']]
请注意,这种方式不能直接比较“已清除”列表,至少如果空列表应与具有任何内容的列表匹配,则至少不能如此。为此,您将需要另一种递归比较方法。
相反,您还可以定义一个保留除列表结构以外的函数,也许您也可以将其用于其他比较...
def leafs(lst):
return [x for y in lst
for x in (leafs(y) if isinstance(y, list) else [y])]
leafs(a)
# [1, 2, 3, 2, 3]
leafs(b)
# [1, 'a', 1, 'abc', 'd']
答案 1 :(得分:0)
以下功能通过比较列表的大小来达到您想要的结果:
def compare_struc(arr1, arr2):
len1 = len(arr1)
len2 = len(arr2)
if len1 == len2:
return True
else:
return False
def main():
testlist1 = [[1],[2],[3]]
testlist2 = [[],[],[]]
answer = compare_struc(testlist1, testlist2)
print("The answer was: ", answer)
main()
输出:
答案是:正确
答案 2 :(得分:0)
从这个问题尚不清楚,确定两个结构是否等效的标准是什么? tobias_k's answer是一个合理的猜测,这是另一个。我认为,如果项目不是列表,或者它是列表但不包含更多列表,则它是“叶”。有了这个,我们可以拥有这个:
def is_leaf(s):
return not (isinstance(s, list) and any(isinstance(i, list) for i in s))
def have_similar_structure(s1, s2):
if is_leaf(s1):
return is_leaf(s2)
elif is_leaf(s2):
return False
# Both are non-leaf
if len(s1) != len(s2):
return False
return all(have_similar_structure(i1, i2) for i1, i2 in zip(s1, s2))
print(have_similar_structure([[[1], [2], [3]], [2], 3], [[[], [], []], [], None]))
# True
print(have_similar_structure([[]], [1, 2, [3]]))
# False
print(have_similar_structure([[]], [1]))
# False