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
15477084a-15477084-il[1,2,3]au lieu de[1,1,3,4]? Pour votre code, vousnewdictdictnewdictvide à 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
newdictdehors de la bouclefor j in matchesmais cela ne fonctionne pas. Je veux supprimer les doublons de valeur en fonction de la clé, donc15477084doit avoir[1,3,4]