11
votes

Éléments communs entre deux listes n'utilisant pas des ensembles dans Python

Je veux compter les mêmes éléments de deux listes. Les listes peuvent avoir des éléments en double, donc je ne peux donc pas convertir cela en jeux et utilisez et opérateur.

a=[2,2,1,1]
b=[1,1,3,3]


6 commentaires

Pourquoi ne voulez-vous pas utiliser des ensembles?


J'ai des éléments dupliqués dans la liste


Quelles sont les valeurs de retour attendues pour [1, 2, 1] et [1, 3, 2] ?


... et quelle est la sortie souhaitée pour [1, 2, 2] et [1, 1, 2] ?


Je suppose qu'il attend [1, 2] dans les deux cas


Basé sur un commentaire ci-dessous, il veut [1,2,1] dans le premier cas. Il n'est toujours pas clair ce qu'il veut pour la seconde.


3 Réponses :


8
votes

Utiliser des ensembles est le plus efficace, mais vous pouvez toujours faire r = [i pour i in l1 si i i-l2] . .


4 commentaires

Une différence distincte: la méthode SET () et SET () suggérée () renvoie une seule valeur commune entre les deux listes (défini ([1]) dans cet exemple) alors que votre solution reviendra [1, 1] et ainsi de suite .


Merci, mais est-ce une solution de perfomence plus?


Je veux la fonction qui retourne [1,1]


@THOMAS: cette solution donne [1, 1] si l1 == [1, 1] et l2 == [1] , mais Il donne [1] si l1 == [1] et l2 == [1, 1] . Est-ce le comportement que vous voulez?



12
votes

dans Python 3.x (et Python 2.7, quand il est publié), vous pouvez utiliser Collections.Counter Pour ce:

from collections import defaultdict

def list_intersection(list1, list2):
    bag = defaultdict(int)
    for elt in list1:
        bag[elt] += 1

    result = []
    for elt in list2:
        if elt in bag:
            # remove elt from bag, making sure
            # that bag counts are kept positive
            if bag[elt] == 1:
                del bag[elt]
            else:
                bag[elt] -= 1
            result.append(elt)

    return result


2 commentaires

Si sac [elt]: ajoute un élément ELT: 0 au sac lorsque elt in bac est faux. Quand (comme l'OP) Il y a peu de doublons, il peut être préférable de faire si elt dans sac et sac [elt]: sinon le sac peut devenir gonflé avec des valeurs 0 inutiles.


@John Machin: Hmm. Bon point. Une alternative serait de veiller à ce que les comptes de sac sont toujours strictement positifs, en suivant un sac [elt] - = 1 avec un si pas le sac [elt]: del sac [elt] . Ensuite, le test si pourrait simplement être si elt in sac: , qui lit plus bien. Je vais éditer la réponse.



0
votes

Silentghost, Mark Dickinson et Lo'oris ont raison, merci beaucoup à signaler ce problème - j'ai besoin d'une partie commune des listes, donc pour:

a = [1,1,1,2]

b = [1,1,3,3]

résultat devrait être [1,1]

Désolé pour commenter dans un endroit non approprié - je me suis inscrit aujourd'hui. < / p>

J'ai modifié vos solutions: xxx


1


1 commentaires

Bienvenue! Vous voudrez peut-être envoyer un e-mail @stackoverflow.com et leur demander de fusionner votre compte nouvellement enregistré avec le compte temporaire précédent. Voir: meta.stackexchange.com/questions/18232/...