Home > database >  How to combine all arguments in two lists if the first element of each list is the same
How to combine all arguments in two lists if the first element of each list is the same

Time:06-03

setting = Subject.objects.annotate(A_setup=Count('id', filter=Q(type='A'), distinct=True) * Value(50),
                      B_setup=Count('id', filter=Q(type='B'), distinct=True) * Value(30),
                      C_setup=Count('id', filter=(~Q(type='A') & ~Q(type='B') & ~Q(type__isnull=True) & Q(id__in=workers.filter(worker=1).values('id')))) * Value(10)) \
            .values('setting__user_id', 'A_setup', 'B_setup', 'C_setup')

setting = [{'setting__user_id': 4, 'A_setting': 50.0, 'B_setting': 120, 'C_setting': 10.0}, {'setting__user_id': 34, 'A_setting': 0.0, 'B_setting': 0, 'C_setting': 0.0}, {'setting__user_id': 33, 'A_setting': 0.0, 'B_setting': 150, 'C_setting': 0.0}, {'setting__user_id': 30, 'A_setting': 0.0, 'B_setting': 150, 'C_setting': 0.0}, {'setting__user_id': 74, 'A_setting': 50.0, 'B_setting': 120, 'C_setting': 10.0}]


uploader = Feedback.objects           .values('uploader_id').distinct().values_list('uploader_id')
uploader = [{'uploader_id': 25}, {'uploader_id': 20}, {'uploader_id': 74}, {'uploader_id': 34}, {'uploader_id': 93}, {'uploader_id': 88}, {'uploader_id': 73}, {'uploader_id': 89}, {'uploader_id': 30}, {'uploader_id': 33}, {'uploader_id': 85}, {'uploader_id': 4}, {'uploader_id': 46}]

"setting" outputs only users who satisfy the conditions. But I need a list of all users. The "uploader" is a queryset containing all users. First, the entire list of users is printed, and if the user's id is included in the "setting", the setting value is output. The final result I want to achieve is as follows.

Desired Result: [['25', '0', '0', '0'], ['20', '0', '0', '0'], ['74', '50', '120', '10'], ['34', '0', '0', '0'], ['93', '0', '0', '0'], ['88', '0', '0', '0'], ['73', '0', '0', '0'], ['89', '0', '0', '0'], ['30', '0', '150', '0'], ['33', '0', '150', '0'], ['35', '0', '0', '0'], ['4', '50', '120', '10'], ['46', '0', '0', '0']]

sorry. Please check again. There are two querysets. I want to get the A_setup, B_setup, C_setup values ​​of setting if uploader id and uploader id of setting are the same after unfolding the uploader queryset, and adding 0 if there is no uploader id in setting. How do I get the results I want?

CodePudding user response:

In my opinion, it is better to change the data structure a little bit (into setting_new and uploader_ids below), and then use list comprehension:

from operator import itemgetter

# setting = [{'setting__user_id': 4, 'A_setting': 50.0, 'B_setting': 120, 'C_setting': 10.0}, ...
# uploader = [{'uploader_id': 25}, {'uploader_id': 20}, {'uploader_id': 74}, ...

setting_new = {dct['setting__user_id']: itemgetter('A_setting', 'B_setting', 'C_setting')(dct) for dct in setting}
uploader_ids = map(itemgetter('uploader_id'), uploader)

output = [[i, *setting_new.get(i, (0,0,0))] for i in uploader_ids]
print(output)
# [[25, 0, 0, 0], [20, 0, 0, 0], [74, 50.0, 120, 10.0], [34, 0.0, 0, 0.0], ...
  • Related