Если вы хотите разрешить дублирование, вам понадобится дополнительное пространство для отслеживания вещей. Однако теперь выбор может быть упрощен до повторения пробела для списка или для набора. В случае, если список больше, чем обычно установленный, первая функция может сэкономить место. Но будьте осторожны: потребуется больше места, если набор больше, чем список.
s = set([ 1, 2, 3, 4 ])
l = [ 1, 2, 3, 5 ]
Подход 1: создает счетчик в порядке набора
def low_space_compare(some_set, some_list):
from collections import Counter
state = Counter(some_set)
for item in some_list:
if item not in state:
print("bad")
return "bad"
state[item] -= 1
if any(val > 0 for val in state.values()): #change to val != 0 if duplicates not allowed
print("bad")
return "bad"
return "good"
С другой стороны, если дубликаты также не разрешены, вы можете просто перебрать список и удалить из набора, не требуя дополнительного места вообще. Но это мутирует набор !!!
Подход 2: без лишнего пространства, не может обрабатывать дураки
def low_space_compare_no_dupes(some_set, some_list):
#need to create a copy of some_set if you (hopefully) take offense to mutating the original set
for item in some_list:
if item not in some_set:
print("bad")
return "bad"
else:
some_set.remove(item) #this makes a dupe value fail when you see it again
if some_set:
print("bad, set had extra stuff")
return "bad"
return "good"
low_space_compare(s, l) #bad
low_space_compare_no_dupes(s, l) #bad
print(s) #{4} uh oh.
Редактировать: Подход 3: наихудший случай такой же, как создание нового набора из списка n в случае, когда его допустимое совпадение, но короткие замыкания:
def low_space_compare_no_counters(some_set, some_list):
new_set = set()
#need to create a copy of some_set if you (hopefully) take offense to mutating the original set
for item in some_list:
if item not in some_set:
if item not in new_set:
print("bad")
return "bad"
else:
pass #ah, a dupe, keep going
else:
some_set.remove(item)
new_set.add(item)
if some_set:
print("bad, set had extra stuff")
return "bad"
return "good"
low_space_compare_no_counters(s, l)