def check(xrr):
""" goes through the list and returns True if the list
does not contain common pairs, IE ([a,b,c],[c,d,e]) = true
but ([a,b,c],[b,a,c]) = false, note the lists can be longer than 2 tuples"""
x = xrr[:]
#sorting the tuples
sorted(map(sorted,x))
for i in range(len(x)-1):
for j in range(len(x)-1):
if [x[i]] == [x[i+1]] and [x[j]] == [x[j+1]]:
return False
return True
但它似乎没有正常工作,这可能是非常基本的东西,但经过几天的尝试,我似乎真的不知道错误在哪里。
提前完成
答案 0 :(得分:1)
我建议使用set
:
def check(xrr):
s = set()
for t in xrr:
u = tuple(sorted(t))
if u in s:
return False
s.add(u)
return True
这样,您无需对整个列表进行排序,并在找到第一个副本时停止。
您的代码中存在多个错误。一个是sorted
返回一个新列表,你只需删除返回值。另一个是你的数据有两个嵌套循环,你只需要一个。以下是使您的方法有效的代码:
def check(xrr):
x = sorted(map(sorted,xrr))
for i in range(len(x)-1):
if x[i] == x[i+1]:
return False
return True
这可以缩短为
def check(xrr):
x = sorted(map(sorted,xrr))
return all(a != b for a, b in zip(x[:-1], x[1:]))
但请注意,我给出的第一个代码会更有效率。
顺便说一句,Python中的列表是[1, 2, 3]
,而元组是(1, 2, 3)
。
答案 1 :(得分:1)
您的代码存在很多问题,正如其他人提到的那样。我将尝试解释如何实现此功能。
听起来你想要做的事实上是这样的:你从输入序列生成一对配对列表,看看它们之间是否有任何重复。当你像这样制定问题时,它实现起来会容易得多。
首先我们需要生成对。它可以通过多种方式完成,您可能会做的是:
def pairs( seq ):
ret = []
# go to the 2nd last item of seq
for k in range(len(seq)-1):
# append a pair
ret.append((seq[k], seq[k+1]))
return ret
现在我们想看(a,b)和(b,a)和相同的元组,所以我们只是对元组进行排序:
def sorted_pairs( seq ):
ret = []
for k in range(len(seq)-1):
x,y = (seq[k], seq[k+1])
if x <= y:
ret.append((x,y))
else:
ret.append((y,x))
return ret
现在解决这个问题非常简单。我们只需要生成所有这些元组并将它们添加到集合中。一旦我们看到一对两次,我们就完成了:
def has_common_pairs( *seqs ):
""" checks if there are any common pairs among any of the seqs """
# store all the pairs we've seen
seen = set()
for seq in seqs:
# generate pairs for each seq in seqs
pair_seq = sorted_pairs(seq)
for pair in pair_seq:
# have we seen the pair before?
if pair in seen:
return True
seen.add(pair)
return False
现在您尝试实现的功能非常简单:
def check(xxr):
return not has_common_pairs(*xxr)
PS:您可以将sorted_pairs函数概括为可以处理任何类型的迭代,而不仅仅是那些支持索引的函数。为了完整起见,我将它粘贴在下面,但你真的不需要它,而且更难理解:
def sorted_pairs( seq ):
""" yield pairs (fst, snd) generated from seq
where fst <= snd for all fst, snd"""
it = iter(seq)
fst = next(it)
for snd in it:
if first <= snd:
yield fst, snd
else:
yield snd, fst
first = snd
答案 2 :(得分:0)
sorted
不会改变来源,它会返回一个新列表。
def check(xrr):
xrrs = map(sorted, xrr)
for i in range(len(xrrs)):
if xrrs[i] in xrrs[i+1:]: return False
return True
答案 3 :(得分:0)
我不确定这是什么,但如果我理解正确,我会写:
def check(lst):
return any(not set(seq).issubset(lst[0]) for seq in lst[1:])
print check([(1, 2, 3), (2, 3, 5)]) # True
print check([(1, 2, 3), (3, 2, 1)]) # False
答案 4 :(得分:0)
这是更一般的解决方案,请注意它找到重复,而不是“非重复”,这样做比使用不更好。
def has_duplicates(seq):
seen = set()
for item in seq:
if hasattr(item, '__iter__'):
item = tuple(sorted(item))
if item in seen:
return True
seen.add(item)
return False
这是查找重复项的更通用的解决方案:
def get_duplicates(seq):
seen = set()
duplicates = set()
for item in seq:
item = tuple(sorted(item))
if item in seen:
duplicates.add(item)
else:
seen.add(item)
return duplicates
同样最好找到重复项,而不是“不重复项”,这样可以避免很多混乱。与单用途函数相比,您最好使用通用和可读的解决方案。