2010-12-12 6 views
0

j'ai écrit un petit programme:tuple vérification en python

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 

Mais il ne semble pas travailler juste, cela est probablement quelque chose de très basique, mais après deux ou trois jours à essayer sur et en dehors, je ne peux pas semble vraiment me faire comprendre où est l'erreur.

Merci à l'avance

+5

Vous êtes encore confusion des tuples et des listes. En outre, "ne semble pas fonctionner correctement" est un rapport de bogue 100% sans valeur - quels résultats obtenez-vous, qu'attendez-vous? – delnan

+0

@delnan Je pense que le résultat escompté est décrit dans la doc-chaîne, mais je suis d'accord sur "liste/tuple encore confus" :) – khachik

+0

La docstring est trompeuse aussi, si la fonction cherche des paires communes (si paires signifie ce que vous 'd attendent, c'est à dire 'paires ([1,2,3,4]) -> [(1,2), (2,3), (3,4)]') alors il ne peut y avoir de 'trié' dans Là. Voir ce qui se passe avec '[1,2,3,4] vs [1,3,5,2]' –

Répondre

1

Il y a tellement de problèmes avec votre code que d'autres l'ont mentionné. Je vais essayer d'expliquer comment j'implémenterais cette fonction.

Il semble que ce que vous voulez faire est réellement ceci: Vous générez une liste de paires à partir des séquences d'entrée et voyez s'il y a des doublons parmi les paires. Lorsque vous formulez le problème de cette manière, il devient beaucoup plus facile à implémenter.

Nous devons d'abord générer les paires.Il peut être fait à bien des égards, celui que vous auriez probablement faire est:

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 

Maintenant, nous voulons voir (a, b) et (b, a) et le même tuple, donc nous trions tout simplement les tuples :

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 

Maintenant, la résolution du problème est assez simple. Nous avons juste besoin de générer tous ces tuples et de les ajouter à un ensemble. Une fois que nous voyons une paire deux fois nous avons terminé:

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 

maintenant la fonction que vous essayez de mettre en œuvre est assez simple:

def check(xxr): 
    return not has_common_pairs(*xxr) 

PS: Vous pouvez généraliser les sorted_pairs fonctionnent à travailler sur tout type de itérable, pas seulement ceux qui supportent l'indexation. Par souci d'exhaustivité je vais le coller ci-dessous, mais vous n'en avez pas vraiment besoin ici et il est plus difficile à comprendre:

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 
1

Je recommande d'utiliser un set pour cela:

def check(xrr): 
    s = set() 
    for t in xrr: 
     u = tuple(sorted(t)) 
     if u in s: 
      return False 
     s.add(u) 
    return True 

De cette façon, vous n'avez pas besoin de trier toute la liste et vous arrêter quand le premier doublon est trouvé.

Il y a plusieurs erreurs dans votre code. L'une est que sorted renvoie une nouvelle liste, et vous venez de supprimer la valeur de retour. Un autre est que vous avez deux boucles imbriquées sur vos données où vous auriez besoin d'un seul. Voici le code qui rend votre travail d'approche:

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 

Cela pourrait être raccourci à

def check(xrr): 
    x = sorted(map(sorted,xrr)) 
    return all(a != b for a, b in zip(x[:-1], x[1:])) 

Mais notez que le premier code que j'ai donné sera plus efficace. Par ailleurs, une liste en Python est [1, 2, 3], tandis qu'un tuple est (1, 2, 3).

+1

Je ne suis pas sûr, mais il semble que cela ne devrait pas fonctionner, vous ne pouvez pas ajouter des listes à un ensemble (vous obtiendrez des 'listes sont impossibles' ou quelque chose comme ça). – khachik

+0

@khachik: Vous avez raison, merci. Je l'ai réparé pour utiliser des tuples. –

0

sorted ne modifie pas la source, elle renvoie une nouvelle liste.

def check(xrr): 
    xrrs = map(sorted, xrr) 
    for i in range(len(xrrs)): 
     if xrrs[i] in xrrs[i+1:]: return False 
    return True 
0

Je ne suis pas sûr que ce ce qui est demandé, mais si j'ai bien compris, j'écrirait:

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 
0

est ici solution plus générale, note qu'il trouve des doublons, et non ' 'non-doublons', c'est mieux de cette façon et que de ne pas l'utiliser.

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 

C'est une solution plus générale des doublons trouver:

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 

En outre, il est préférable de trouver des doublons, et non les « pas de doublons », il permet d'économiser beaucoup de confusion. Vous êtes mieux d'utiliser une solution générale et lisible, que des fonctions à usage unique.

Questions connexes