1
votes

Comparer des listes de dictionnaires en fonction de valeurs

J'ai deux listes de dictionnaires comme:

filter_data = []
for nd in new_data:
    if nd['company'] not in [d['company'] for d in old_data]:
        filter_data.append(nd)
    elif nd['company'] in [d['company'] for d in old_data]:
        date_ = # logged_in time of the company from old_data
        filter_data.append(nd if nd['logged_in']> date_)
filter_data

Je suis intéressé à obtenir l'élément de liste à partir de new_data uniquement si:

  1. La société dans new_data n'est pas dans old_data
  2. Si la société est à la fois dans new_data et old_data, uniquement si le temps de connexion dans new_data est postérieur à old_data

Résultat attendu:

[{'company': 'Amazon', 'logged_in': '2019-01-26'},
 {'company': 'LinkedIn', 'logged_in': '2019-04-20'},
 {'company': 'Wiki', 'logged_in': '2019-04-20'}]

Jusqu'à présent, j'ai essayé:

old_data = [{'company': 'Amazon', 'logged_in': '2019-01-20'},
            {'company': 'Facebook', 'logged_in': '2019-04-20'},
            {'company': 'Google', 'logged_in': '2019-04-20'}]

new_data = [{'company': 'Amazon', 'logged_in': '2019-01-26'},
            {'company': 'Facebook', 'logged_in': '2019-04-12'},
            {'company': 'LinkedIn', 'logged_in': '2019-04-20'},
            {'company': 'Wiki', 'logged_in': '2019-04-20'}]


0 commentaires

5 Réponses :


2
votes
[{'company': 'Amazon', 'logged_in': '2019-01-26'},
 {'company': 'LinkedIn', 'logged_in': '2019-04-20'},
 {'company': 'Wiki', 'logged_in': '2019-04-20'}]

2 commentaires

Vous pouvez éliminer les conversions datetime et comparer simplement les chaînes car elles sont au format ISO 8601.


@benvc Merci ... je n'y ai pas pensé.



0
votes

Voici un moyen de le faire, en supposant que les noms de société dans old_data ne soient pas répétés:

old_data_dict = {}
for d in old_data:
    old_data_dict[d['company']] = max(d['logged_in'],
                                      old_data_dict.get(d['company'], ''))

EDIT: Si old_data peut contenir plusieurs dictionnaires avec le même nom de société, vous pouvez définir old_data_dict comme suit à la place:

old_data = [{'company': 'Amazon', 'logged_in': '2019-01-20'},
            {'company': 'Facebook', 'logged_in': '2019-04-20'},
            {'company': 'Google', 'logged_in': '2019-04-20'}]

new_data = [{'company': 'Amazon', 'logged_in': '2019-01-26'},
            {'company': 'Facebook', 'logged_in': '2019-04-12'},
            {'company': 'LinkedIn', 'logged_in': '2019-04-20'},
            {'company': 'Wiki', 'logged_in': '2019-04-20'}]
# Make dictionary mapping company names to logged in times
old_data_dict = {d['company']: d['logged_in'] for d in old_data}
# Make result by comparing logged in times to previous value or empty string
result = [d for d in new_data if d['logged_in'] > old_data_dict.get(d['company'], '')]
# Print result
print(*result, sep='\n')
# {'company': 'Amazon', 'logged_in': '2019-01-26'}
# {'company': 'LinkedIn', 'logged_in': '2019-04-20'}
# {'company': 'Wiki', 'logged_in': '2019-04-20'}


0 commentaires

0
votes

Si vous utilisez un dictionnaire à index inversé old_dic , cela devient facile:

[{'company': 'Amazon', 'logged_in': '2019-01-26'},
 {'company': 'LinkedIn', 'logged_in': '2019-04-20'},
 {'company': 'Wiki', 'logged_in': '2019-04-20'}]

renvoie:

old_data = [{'company': 'Amazon', 'logged_in': '2019-01-20'},
            {'company': 'Facebook', 'logged_in': '2019-04-20'},
            {'company': 'Google', 'logged_in': '2019-04-20'}]

new_data = [{'company': 'Amazon', 'logged_in': '2019-01-26'},
            {'company': 'Facebook', 'logged_in': '2019-04-12'},
            {'company': 'LinkedIn', 'logged_in': '2019-04-20'},
            {'company': 'Wiki', 'logged_in': '2019-04-20'}]

old_dic = {o["company"]: {"logged_in": o["logged_in"]} for o in old_data}

result = [
    n for n in new_data 
    if n["company"] not in s or 
       n["logged_in"] > old_dic[n["company"]]["logged_in"]
]

p>


0 commentaires

0
votes

Essayer de reprendre là où vous vous étiez arrêté:

[{'company': 'Amazon', 'logged_in': '2019-01-26'},
 {'company': 'LinkedIn', 'logged_in': '2019-04-20'},
 {'company': 'Wiki', 'logged_in': '2019-04-20'}]

Résultat:

def find_logged_in(company, olddata):
    for od in olddata:
        if od['company']==company:
            return od['logged_in']
    return None


filter_data = []
for nd in new_data:
    if nd['company'] not in [d['company'] for d in old_data]:
        filter_data.append(nd)
    elif nd['company'] in [d['company'] for d in old_data]:
        date_ = find_logged_in(nd['company'], old_data) 
        if nd['logged_in'] > date_:
            filter_data.append(nd)
filter_data


0 commentaires

0
votes

vous pouvez le faire en utilisant des pandas:

from pandas import DataFrame
a = DataFrame(new_data+old_data).groupby('company',as_index=False).max().to_dict('record')
filter_data = [x for x in a if x not in b]


0 commentaires