这些列表是否相等?


19

如您所知,python有列表。您可能不知道这些列表可以包含自己。

a = []
a.append(a)

Python 2

Python 3

这些很酷,您可以使用它们做很多有趣的事情,但是您无法将它们进行比较。

a = []
a.append(a)
b = []
b.append(b)
a == b

Python 2

Python 3

任务

您的工作是用Python(或可以直接处理python对象的任何语言)编写一个函数,该函数将包含两个可能包含自身的列表并进行比较。

如果两个列表具有相同的长度,并且不存在数字序列,则两个列表是相等的,因此按此序列对两个列表进行索引会导致在此相等定义下两个对象不相等。为了简单起见,列表中包含的所有非列表对象都是python整数,应将其与python的内置相等性进行比较。

您的程序不应依赖python的递归深度来确定列表是否无限深。那是:

def isInfinite(a,b):
 try:
  a==b
  return False
 except RunTimeError:
  return True

这不是确定两个列表是否为自引用的有效方法。

测试用例

假设您定义一个函数 equal

a = []
a.append(a)
b = []
b.append(b)
print(equal(a,b))

True

a = []
b = []
a.append(b)
b.append(a)
print(equal(a,b))

True

a = []
b = []
a.append(1)
a.append(b)
b.append(1)
b.append(a)
print(equal(a,b))

True

a = []
a.append(a)
b = [a]
print(equal(a,b))

True

a = []
b = []
c = []
a.append(b)
b.append(c)
c.append(a)
equal(a,b)

True

a=[1,[2]]
b=[1,[2,[1]]]
a[1].append(a)
b[1][1].append(b[1])

True

a = []
a.append(a)
b = [1]
b.append(a)
c = [1]
c.append([c])
print(equal(b,c))

False

a = []
b = []
a.append(1)
a.append(b)
b.append(a)
b.append(1)
print(equal(a,b))

False

a = []
b = []
a.append(a)
b.append(b)
b.append(b)
print f(a,b)

False

17
作为一个侧面说明潜在的选民:请注意,一般语言的具体挑战是令人难以接受的 ,除了在某些情况下(如那些只在某些语言有趣的任务)。IMO,这是针对特定语言的挑战的绝妙示例。
DJMcMayhem

@WheatWizard这还不够—嵌套列表的长度也必须相同。
xnor

@WheatWizard您实际上可以比较它们。在Python中,如果它们不相等,则只会得到“超出了递归限制”。tio.run/nexus/…– mbomb007
'04

@ mbomb007那是因为python默认情况下会比较引用。如果您有两个具有不同引用的相同对象,它将失败,因此将面临挑战。
小麦巫师

2
您可以将挑战扩展到列表可以包含自身的所有语言吗?
CalculatorFeline

Answers:


9

Python 2,94个字节

g=lambda c,*p:lambda a,b:c in p or all(map(g((id(a),id(b)),c,*p),a,b))if a>[]<b else a==b
g(0)

在线尝试!

isaacg非常聪明的解决方案的改进,该解决方案存储id正在处理的列表对,如果在较低级别出现相同的比较,则声明它们相等。

递归步骤all(map(...,a,b))ab相等,如果它们中所有对应的元素对都相等。这很好地拒绝了不等长,因为用map填充最短的列表Nonezip这与截断不同。由于实际列表都不包含None,因此这些填充列表将始终被拒绝。


,之后的目的是什么c
小麦巫师

它使其成为一个元组。
mbomb007 '17

a=[];a+=[a,1];b=[];b+=[b,2];f(a,b)溢出堆栈,a=[1];b=[2];f(a,b);f(a,b)看起来像一个可重用性问题。
Anders Kaseorg '17

我看到了@AndersKaseorg,对列表进行变异是在麻烦。我认为这可以解决。
xnor

1
@AndersKaseorg我看到您编写了基本相同的功能于函数的解决方案。有一个没有这个的95字节解决方案:f=lambda a,b,p=[0]:p[0]in p[1:]or all(map(f,a,b,[[(id(a),id(b))]+p]*len(a)))if a>[]<b else a==b。也许有更好的方法来处理map
xnor

5

Python中,233个 218 197 217字节

d=id
def q(a,b,w):
 w[(d(a),d(b))]=0
 if d(a)==d(b):return 1
 if(a>[]and[]<b)-1:return a==b
 if len(a)!=len(b):return 0
 for x,y in zip(a,b):
  if((d(x),d(y))in w or q(x,y,w))-1:return 0
 return 1
lambda a,b:q(a,b,{})

最后一行的匿名函数执行所需的功能。

这仍然是打高尔夫球的过程,我只是想证明这是可能的。

本质上,如果我们正在处理给定的支票,则在w中输入一个条目。如果它们是同一对象,不是列表且相等,或者它们的所有元素相等或正在处理,则两件事相等。


您不能使用a>[]代替i(a,list)吗?
mbomb007 '17

@ mbomb007这是在添加“一切都是列表或整数”规则之前编写的。将更新。
isaacg '17

您可以使用a>[]<bandlen(a)-len(b)
mbomb007

@ETHproductions哦,他的字节数错了。这就是为什么
mbomb007 '04

d(a)==d(b)a is b?这将减少的两个用途d
xnor
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.