2

2 つのリストを比較して、一方が他方のローテーション (巡回順列) であるかどうかを判断しようとしています。

a = [1, 2, 3]
b = [1, 2, 3] or [2, 3, 1] or [3, 1, 2]

はすべて一致しますが、次のようになります。

b = [3, 2, 1] is not

これを行うには、次のコードを用意しました。

def _matching_lists(a, b):
    return not [i for i, j in zip(a,b) if i != j]

def _compare_rotated_lists(a, b):
    rotations = [b[i:] + b[:i] for i in range(len(b))]
    matches = [i for i in range(len(rotations)) if _matching_lists(a, rotations[i])]
    return matches

これにより、b のすべての可能な回転のリストが作成され、それぞれが比較されます。中間リストを作成せずにこれを行うことは可能ですか? 通常、リストは 4 項目の長さしかないため、パフォーマンスは重要ではありません。私の主な関心事は、コードの明快さです。

リストは常に同じ長さになります。

最良の答え(一致するローテーションのリストを保持する)は次のようです:

def _compare_rotated_lists(a, b):
    return [i for i in range(len(b)) if a == b[i:] + b[:i]]
4

4 に答える 4

2

私の理解が正しければ、bが の順列でaあるがa逆ではないかどうかを調べたいですか? 非常にシンプルで読みやすく、一般的な解決策があります。

>>> from itertools import permutations 
>>> a = (1, 2, 3)
>>> b = (3, 1, 2)
>>> c = (3, 2, 1)
>>> results = set(permutations(a)) - set((a, tuple(sorted(a, reverse=True))))
>>> b in results
True
>>> c in results
False
于 2013-04-02T20:42:43.413 に答える
1

どうですか:

def canon(seq):
    n = seq.index(min(seq))
    return seq[n:] + seq[:n]

def is_rotation(a, b):
    return canon(a) == canon(b)

print is_rotation('abcd', 'cdab') # True
print is_rotation('abcd', 'cdba') # False

2 つのリストが互いに回転しているかどうかを確認するためだけに、すべての回転を生成する必要はありません。

于 2013-04-02T20:54:02.973 に答える
0

このコードをいくつかの例でテストしたところ、うまく機能しました。

def compare(a,b):
firstInA = a[0]
firstInB = b.index(firstInA)
secondInA = a[1]
secondInB = b.index(secondInA)
if (secondInB == firstInB + 1) or (secondInB == 0 and firstInB == 2):
    return True
else:
    return False

私は試した:

a = [1,2,3]
b = [1,2,3]
print(compare(a,b))
c = [1,2,3]
d = [3,1,2]
print(compare(c,d))
e = [1,2,3]
f = [3,2,1]
print(compare(e,f))

True, True,False これはサイズ 3 のリストでのみ機能します。さらに必要な場合は、ステートメント内にthirdInAifと thirdInB を追加します。リストの長さよりも常に 1 つ少なくする必要があります。 1 つが所定の位置にある場合、最後に残るのはその場にあるだけです。

于 2013-04-02T20:42:34.993 に答える