J'ai une structure de données:
new_matches = [] for j in matches: newdict = dict() for key,value in j.items(): if key in newdict.keys(): if value not in newdict[key]: newdict[key].append(value) new_matches.append(newdict) else: newdict[key] = value new_matches.append(newdict)
Je veux vérifier si la clé et la valeur de la clé sont des doublons, je vais la supprimer. Si la clé et la valeur ont de nombreuses valeurs différentes, je les combinerai.
J'espère que mon résultat ressemble à:
matches = [ { "15477084": [1,3,4] }, { "360418": [2] } ]
Voici mon code:
matches = [ { "15477084": [1] }, { "360418": [2] }, { "15477084": [1] }, { "15477084": [3,4] } ]
Mais mon résultat est faux (mon résultat est le même avec les correspondances de données). Je ne sais pas pourquoi mon résultat est faux.
6 Réponses :
Vous pouvez essayer ceci:
defaultdict(set, {'15477084': {1, 3, 4}, '360418': {2}})
production:
from collections import defaultdict v = defaultdict(set) for dict_values in matches: for key, value in sorted(dict_values.items()): print(key) for i in value: v[key].add(i)
print([{k: list(set(v))} for k, v in result.items()])
Merci pour votre solution, mais je veux 15477084
avait des valeurs [1,3,4]
Je veux supprimer les doublons
Vous pouvez modifier la sortie finale comme cette print([{k: list(set(v))} for k, v in result.items()])
ou utiliser un set
dans le defaultdict
comme d'autres l'ont fait.
Pouvez-vous m'expliquer pourquoi vous ajoutez {k: list(set(v))}
, les données supprimeront les doublons? Je suis un débutant avec python de compréhension. Désolé si ma question vous rend ennuyeux
La fonction set()
convertit vos données en un ensemble qui ne contiendra que des éléments uniques (vous avez raison, pas de doublons) et la fonction list()
les reconvertira en liste.
Essaye ça:
{'15477084': [1, 3, 4], '360418': [2]}
Production:
from collections import defaultdict from itertools import chain res = defaultdict(list) for x in matches: (k,) = x if x[k] not in res[k]: res[k].append(x[k]) res = {k: list(chain(*v)) for k, v in res.items()} print(res)
merci beaucoup, mais dans `res = {k: list (chain (* v)) pour k, v dans res.items ()} je ne comprends pas pourquoi vous faites ça. Peux-tu m'expliquer
valeurs dans res
dict est la liste des listes que je fais un lsit plat à partir de cela
Il chain.from_iterable(v)
peut-être mieux faire chain.from_iterable(v)
au lieu de chain(*v)
.
Parce que j'aime les pandas, je propose un moyen spécial de résoudre votre problème. Peut-être que vous l'aimerez.
{'15477084': [1, 3, 4], '360418': [2]}
C'est le résultat
import json import pandas as pd if __name__ == "__main__": matches = [ {"15477084": [1]}, {"360418": [2]}, {"15477084": [1]}, {"15477084": [3, 4]}, ] matches_df = pd.DataFrame(matches) matches_df = matches_df.fillna("[]").transpose().astype(str).apply( lambda x: list( set([record for sub in x.tolist() for record in json.loads(sub)]) ), axis=1, ) result = matches_df.to_dict() print(result)
C'est la nouvelle solution pour résoudre mes problèmes, merci beaucoup.
defaultdict peut vous aider ici
{'15477084': [1, 3, 4], '360418': [2]}
Production
from collections import defaultdict res_matches = defaultdict(list) for i in matches: key, value = list(i.keys())[0], list(i.values())[0] to_add = set(value).difference(set(res_matches[key])) if to_add: res_matches[key].extend(to_add) print(dict(res_matches))
Le problème avec votre programme est que newdict sera créé pour chaque itération et qu'il n'aura pas de paires clé-valeur, donc l'instruction (si la clé dans newdict.keys ()) sera toujours fausse, donc sinon l'instruction sera exécutée et il ajoutera le dictionnaire dans la liste des correspondances dans new_matches.
Et aussi l'instruction (si value pas dans newdict [key]), ici value est une liste et newdict [key] sera aussi une liste (si vous avez résolu le problème mentionné ci-dessus), vous comparez donc deux listes. ie) [1] == [3,4] qui ne sera pas vrai. Au lieu de cela, vous devez itérer chaque valeur de l'une des listes et la comparer avec une autre liste.
J'ai fourni la solution en résolvant les deux problèmes de votre programme.
matches = [ { "15477084": [1] }, { "360418": [2] }, { "15477084": [1] }, { "15477084": [3,4] } ] new_matches = [] for j in matches: newdict = dict() for key,value in j.items(): if len(new_matches) != 0: for k in new_matches: if key in k.keys(): for i in value: if i not in k[key]: k[key].append(i) break else: newdict[key] = value new_matches.append(newdict) else: newdict[key] = value new_matches.append(newdict) print(new_matches)
Pourquoi
15477084
a-15477084
-il[1,2,3]
au lieu de[1,1,3,4]
? Pour votre code, vousnewdict
dictnewdict
vide à chaque itération, doncif key in newdict.keys()
sera toujoursFalse
, et ne différera donc pas de l'entrée d'origine.@Chris J'ai essayé la position
newdict
dehors de la bouclefor j in matches
mais cela ne fonctionne pas. Je veux supprimer les doublons de valeur en fonction de la clé, donc15477084
doit avoir[1,3,4]