在python中检查元组

时间:2010-12-12 14:24:26

标签: python tuples

我写了一个小程序:

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

但它似乎没有正常工作,这可能是非常基本的东西,但经过几天的尝试,我似乎真的不知道错误在哪里。

提前完成

5 个答案:

答案 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_pa​​irs函数概括为可以处理任何类型的迭代,而不仅仅是那些支持索引的函数。为了完整起见,我将它粘贴在下面,但你真的不需要它,而且更难理解:

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

同样最好找到重复项,而不是“不重复项”,这样可以避免很多混乱。与单用途函数相比,您最好使用通用和可读的解决方案。