我正在创建一个列表列表,并希望防止欺骗。例如,我有:
mainlist = [[a,b],[c,d],[a,d]]
要添加的下一个项目(列表)是[b,a]
,它被视为[a,b]
的副本。
mainlist = [[a,b],[c,d],[a,d]]
swap = [b,a]
for item in mainlist:
if set(item) & set(swap):
print "match was found", item
else:
mainlist.append(swap)
关于如何测试下一个要添加的项目是否已经在列表中的任何建议?
答案 0 :(得分:3)
以下是使用frozenset
内set
来检查重复项的方法。由于我正在调用一个适用于全局变量的函数,所以它有点难看。
def add_to_mainlist(new_list):
if frozenset(new_list) not in dups:
mainlist.append(new_list)
mainlist = [['a', 'b'],['c', 'd'],['a', 'd']]
dups = set()
for l in mainlist:
dups.add(frozenset(l))
print("Before:", mainlist)
add_to_mainlist(['a', 'b'])
print("After:", mainlist)
输出:
Before: [['a', 'b'], ['c', 'd'], ['a', 'd']]
After: [['a', 'b'], ['c', 'd'], ['a', 'd']]
显示新列表确实未添加到原始列表中。
这是一个更干净的版本,可以在一个函数内动态计算现有的set
,该函数可以在本地执行所有操作:
def add_to_mainlist(mainlist, new_list):
dups = set()
for l in mainlist:
dups.add(frozenset(l))
if frozenset(new_list) not in dups:
mainlist.append(new_list)
return mainlist
mainlist = [['a', 'b'],['c', 'd'],['a', 'd']]
print("Before:", mainlist)
mainlist = add_to_mainlist(mainlist, ['a', 'b']) # the assignment isn't needed, but done anyway :-)
print("After:", mainlist)
这就是你正在做的事情:
...
for item in mainlist:
if set(item) & set(swap):
print "match was found", item
else:
mainlist.append(swap)
你正在交叉两套并检查结果的真实性。虽然这可能适用于0个交叉点,但即使其中一个元素很常见(例如,['a', 'b']
和['b', 'd']
),您仍然会声明一个错误的匹配。
理想情况下,您需要检查结果集的长度,并确保其长度等于2:
dups = False
for item in mainlist:
if len(set(item) & set(swap)) == 2:
dups = True
break
if dups == False:
mainlist.append(swap)
理想情况下,您还需要一个标记,以确保您没有找到重复项。您之前的代码会添加,而不会先检查所有项目。
答案 1 :(得分:1)
如果您的内部列表的顺序无关紧要,那么可以使用frozenset()
s来完成此操作:
>>> mainlist = [['a', 'b'],['c', 'd'],['a', 'd']]
>>> mainlist = [frozenset(sublist) for sublist in mainlist]
>>>
>>> def add_to_list(lst, sublist):
... if frozenset(sublist) not in lst:
... lst.append(frozenset(sublist))
...
>>> mainlist
[frozenset({'a', 'b'}), frozenset({'d', 'c'}), frozenset({'a', 'd'})]
>>> add_to_list(mainlist, ['b', 'a'])
>>> mainlist
[frozenset({'a', 'b'}), frozenset({'d', 'c'}), frozenset({'a', 'd'})]
>>>
如果订单确实重要,您可以执行@Coldspeed建议的操作 - 从列表中构建set()
,从要添加的列表构建frozenset()
,并测试成员资格 - 或者您可以使用all()
和sorted()
来测试要添加的列表是否等同于任何其他列表:
>>> def add_to_list(lst, sublist):
... for l in lst:
... if all(a == b for a, b in zip(sorted(sublist), sorted(l))):
... return
... lst.append(sublist)
...
>>> mainlist
[['a', 'b'], ['c', 'd'], ['a', 'd']]
>>> add_to_list(mainlist, ['b', 'a'])
>>> mainlist
[['a', 'b'], ['c', 'd'], ['a', 'd']]
>>>