これらのリストは同等ですか?


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オブジェクトを直接処理できる任意の言語)で関数を記述し、それ自体を含む2つのリストを取得して比較することです。

2つのリストが同じ長さであり、番号のシーケンスが存在しない場合、そのシーケンスで両方のリストにインデックスを付けると、2つのオブジェクトは、この等しいという定義の下で等しくなくなります。リストに含まれるすべての非リストオブジェクトは、簡単にするためにPython整数になります。整数のPythonの組み込みの同等性と比較する必要があります。

リストが無限に深いかどうかを判断するために、プログラム Pythonの再帰の深さに依存してはなりません。あれは:

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

2つのリストが自己参照であるかどうかを判断する有効な方法ではありません。

テストケース

関数を定義すると仮定します 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

@ mbomb007これは、Pythonがデフォルトで参照を比較するためです。異なる参照を持つ2つの同一のオブジェクトがある場合、それは失敗するため、課題となります。
小麦ウィザード

2
リストに自分自身を含めることができるすべての言語にこの課題を拡張できますか?
電卓

回答:


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、これらの要素のすべての対応する対が等しい場合等しいです。これは、切り捨てられるのmapNoneは異なり、最短のリストにを埋め込むため、不等長を拒否するのにうまく機能しzipます。実際のリストにはが含まれていないためNone、これらの埋め込みリストは常に拒否されます。


,後の目的は何cですか?
小麦ウィザード

タプルにします。
mbomb007

a=[];a+=[a,1];b=[];b+=[b,2];f(a,b)スタックをオーバーフローさせa=[1];b=[2];f(a,b);f(a,b)、再利用性の問題のように見えます。
アンダースカセオルグ

@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

パイソン、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にエントリを追加します。2つのことは、それらが同じオブジェクトである場合、それらがリストではなく、等しい場合、またはそれらのすべての要素が等しいか、作業中の場合、等しくなります。


a>[]代わりに使用できませんi(a,list)か?
mbomb007

@ mbomb007これは、「すべてがリストまたは整数である」ルールが追加される前に書かれました。更新されます。
isaacg

あなたは使用することができますa>[]<blen(a)-len(b)
mbomb007

@ETHproductionsああ、彼のバイト数が間違っています。だから
mbomb007

することd(a)==d(b)ができますa is bか?これにより、の2つの用途が削減されますd
XNOR
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.