是否有一种更有效的方法来确保list
包含set
的所有且仅包含其他元素,然后从set
构造另一个list
? / p>
例如避免了复制列表和对列表进行排序
s = set([ 1, 2, 3, 4 ])
l = [ 1, 2, 3, 5 ]
if s!=set(l):
print "bad list"
答案 0 :(得分:3)
通过使用列表调用集合的symmetric_difference
方法,可以避免从列表构造另一个集合:
if s.symmetric_difference(l):
print "bad list"
答案 1 :(得分:1)
如果您希望允许重复,则需要某种额外的空间来跟踪事物。但是,现在可以将选择简化为重复列表或集合的空间。如果列表大于通常的列表,则第一个功能可以节省一些空间。但请注意:如果集合大于列表,则会占用更多空间。
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)