12
votes

Comparer deux listes et imprimer uniquement les différences? (Xoring deux listes)

J'essaie de créer une fonction qui prend 2 listes et renvoie la liste qui n'a que les différences des deux listes.

Exemple: P>

def xor(list1, list2):
    list3=list1+list2
    for i in range(0, len(list3)):
        x=list3[i]
        y=i
        while y>0 and x<list3[y-1]:
            list3[y]=list3[y-1]
            y=y-1
        list3[y]=x

        last=list3[-1]
    for i in range(len(list3) -2, -1, -1):
        if last==list3[i]:
            del list3[i]
        else:
            last=list3[i]

    return list3 
print xor([1,2,5,7,8],[1,2,4,8,9])


0 commentaires

6 Réponses :


5
votes

Remarque: Ceci est vraiment incimthonique et ne doit être utilisé que comme une réponse aux devoirs :)

Après avoir triché les deux listes, vous pouvez trouver des doublons en procédant comme suit:

1) Placez les itérateurs au début de A et B

2) Si AItre est supérieur à BitR, avance BitR après avoir placé la valeur de BitR dans la liste de retour

3) sinon si BitR est supérieur à AI2, ADRIVER AIRIER après avoir placé la valeur d'AItre dans la liste de retour

4) sinon vous avez trouvé un duplicata, avancez AI2 et BITR


4 commentaires

Pourquoi pensez-vous que votre approche est omythonique?


@gnibbler Voir la réponse de Sheng pour ce que je considère Pythonic


Qui repose sur les éléments tout en étant hachables. (Ils sont probablement)


Deux implémentations de l'algorithme .



17
votes

L'ensemble d'utilisations est meilleur xxx

grâce à @DSM, une meilleure phrase est la suivante: xxx

Ces deux déclarations sont identiques. Mais ce dernier est plus clair.

Mise à jour: Désolé, je n'ai pas vu la dernière exigence: impossible d'utiliser ensemble. Autant que je sache, la solution fournie par @sashkello est la meilleure.


5 commentaires

Une bonne réponse pour le travail non-travail, mais je ne peux pas utiliser de modules spéciaux, .sort, set ou quoi que ce soit, juste des boucles essentiellement. '


Pourquoi pas simplement définir (a) ^ Set (b) , si nous utilisons des ensembles?


@DSM merci, votre suggestin est meilleur. J'oublie juste la grammaire.


En fait, j'aime symétric_difefence autant que ^ , mais je préfère soit à la version longue d'origine que vous avez eue. Mais vous l'avez changé en Symmetric_Difefence en même temps, j'ai commenté. : ^)


Mise à jour de Sheng, nous pouvons le convertir en liste par simple liste (définir (a) ^ Set (B)) # renvoie une liste



17
votes

Vous voulez essentiellement ajouter un élément à votre nouvelle liste s'il est présent en un et non présent dans un autre. Voici une boucle compacte qui peut le faire. Pour chaque élément dans les deux listes (les concaténate avec list1 + list2 code>), nous ajoutons un élément s'il n'est pas présent dans l'un d'eux:

def xor(list1, list2):
    outputlist = []
    list3 = list1 + list2
    for i in range(0, len(list3)):
        if ((list3[i] not in list1) or (list3[i] not in list2)) and (list3[i] not in outputlist):
             outputlist[len(outputlist):] = [list3[i]]
    return outputlist


7 commentaires

Je pense que je comprends ce que ça fait, mais comment puis-je en faire cela dans une boucle totale et que je ajoute cette boucle à la fonction d'origine ou que cela fonctionnerait-il seul ...


Il s'agit d'une doublure qui fait la fonction que vous créez ... Vous êtes en boucle via List1 + List2 ÉLÉMENTS X et avez deux ifs: 1. Si l'élément de la liste1, faites le flag1 = true, 2. Si l'élément de la liste2, faites le flag2 = Vrai; Si (Flag1 et Flag2)! = True et x non dans la liste de sortie, ajoutez-le à la liste de sortie.


@ user2314520 Qu'est-ce que Sashkello signifie que la compréhension de la liste est équivalente à un pour en boucle sur les éléments du démonteur, qui ajoute lesdits éléments à une nouvelle liste si elles correspondent à la condition, puis en utilisant la liste résultante. .


@ user2314520, j'ai ajouté une version longue.


@ user2314520: Une autre façon de regarder c'est: elle trouve une union des deux listes sans inclure une intersection des listes (c'est-à-dire qu'il trouve Différence symétrique ). Union est list1 + list2 . Un élément x est dans l'intersection si x est dans list1 et x est dans list2 ; Vous souhaitez exclure ces éléments afin que la condition soit inversée: non (x in list1 et x in list2) équivalent à x non dans la liste1 ou x non dans la liste2 . Mettre tout ensemble xor_list = [x pour x dans (list1 + list2) si x pas dans list1 ou x pas dans list2] .


@sashkello: Voici une version légèrement plus lisible de votre code multiligne (Remarque: il conserve des doublons s'ils ne présentent que une liste (ainsi que le code qui utilise la compréhension de la liste)).


@ J.f.sebastian merci, oui, j'ai supposé que nous n'avons pas (et probablement pas de ne pas vouloir) duplicate.



1
votes

simple, mais pas particulièrement efficace :) xxx

ou avec "juste des boucles" xxx


0 commentaires

3
votes

Ce code fonctionne en supposant que vous avez des listes triées. Cela fonctionne dans le temps linéaire, plutôt que quadratique comme de nombreuses autres solutions données.

def diff(sl0, sl1):
    i0, i1 = 0, 0
    while i0 < len(sl0) and i1 < len(sl1):
        if sl0[i0] == sl1[i1]:
            i0 += 1
            i1 += 1
        elif sl0[i0] < sl1[i1]:
            yield sl0[i0]
            i0 += 1
        else:
            yield sl1[i1]
            i1 += 1
    for i in xrange(i0, len(sl0)):
        yield sl0[i]
    for i in xrange(i1, len(sl1)):
        yield sl1[i]

print list(diff([1,2,5,7,9], [1,2,4,8,9]))


1 commentaires

+1 pour la solution linéaire. En général, Vous pouvez l'adapter pour accepter tout iTérable , implémentant essentiellement L'algorithme de Patashu .



3
votes

Essayez ceci,

    a = [1,2,5,7,9]
    b = [1,2,4,8,9]
 print set(a).symmetric_difference(set(b))


0 commentaires