6.1. リストの差分
リストの差分を求めるときは try 文だと速いです。
完全に同じなら True
[1, 2, 3, 4] == [1, 2, 3, 4]
# True
たとえ中身が同じでも 順番が違えば False
[1, 2, 3, 4] == [4, 3, 2, 1]
# False
リストの中身を比較したい場合は、 list クラスから set クラスに変換してしまう。
# 一致(等しいかどうか)
set([1, 2, 3, 4]) == set([4, 3, 2, 1])
# True
# 差分(リストの要素の引き算)
list(set([1, 2, 3, 4]) - set([2, 3, 4]))
# [1]
# 重複(共通の要素を抜き出す)
list(set([1, 2, 3, 4]) & set([3, 4, 5, 6]))
# [3, 4]
WARNING
重複している要素があるリストには使えません。
単純に set にいれて比較してしまうのが簡単そうですが、 複数の要素があった場合に正しく判定できません。
>>> # 一致(等しいかどうか)
>>> # 比較 False になって欲しい。
>>> set([1, 1, 2, 3]) == set([1, 2, 3])
True
>>>
>>> # 差分(リストの要素の引き算)
>>> # 引き算 1, 2 が欲しい。
>>> list(set([1, 2, 2, 4]) - set([2, 3, 4]))
[1]
>>>
>>> # 重複(共通の要素を抜き出す)
>>> # 共通する要素を取り出す 1, 1 が欲しい
>>> list(set([1, 1, 3]) & set([1, 1, 2]))
[1]
>>>
Python に限らず、数学では一般に集合は重複を許さないらしいです。 ちなみに重複を許す集合は、多重集合 multiset (opens new window) と言ったりするらしい。
>>> # set を使うと重複は除外されてしまう。
>>> set([1, 1, 2, 3])
{1, 2, 3}
>>>
>>> set([1, 2, 2, 4])
{1, 2, 4}
>>>
>>> set([1, 1, 3])
{1, 3}
>>>
重複を許すようなリストを比較する場合は、 次のように関数を定義して、中身を一つ一つ比較する他なさそうです。
#
# 新しく定義した関数の使い方
#
# 一致(等しいかどうか)
equal_list([1, 1, 2, 3], [1, 2, 3])
# False
# 差分(リストの要素の引き算)
subtract_list([1, 2, 2, 4], [2, 3, 4])
# [1, 2]
# 重複(共通の要素を抜き出す)
intersect_list([1, 3, 1], [1, 1, 2])
# [1, 1]
#
# 新しく定義した関数
#
def equal_list(lst1, lst2):
lst = lst1.copy()
for element in lst2:
try:
lst.remove(element)
except ValueError:
break
else:
if not lst:
return True
return False
def subtract_list(lst1, lst2):
lst = lst1.copy()
for element in lst2:
try:
lst.remove(element)
except ValueError:
pass
return lst
def intersect_list(lst1, lst2):
arr = []
lst = lst1.copy()
for element in lst2:
try:
lst.remove(element)
except ValueError:
pass
else:
arr.append(element)
return arr
subtract_list
関数について、
以下の記事でコードの解説をさせていただきました。
ただ重箱の隅をつつくようなことをしているので、
ご興味があったとしても、
簡単に読み流していただければと思います。