1

I have 2 json files: rooms.json students.json I need to unit them to another list by the room id's and attribute room in students.json rooms.json :

[
{
    "id": 0,
    "name": "Room #0"
},
{
    "id": 1,
    "name": "Room #1"
},
{
    "id": 2,
    "name": "Room #2"
}
]

students.json:

[
{
    "id": 0,
    "name": "Ryan Keller",
    "room": 1
},
{
    "id": 1,
    "name": "Brooke Ferrell",
    "room": 1
},
{
    "id": 2,
    "name": "Travis Tran",
    "room": 0
}
]

Im using this:

import json

rooms_file = 'rooms.json'
with open(rooms_file) as f:
    rooms_new = json.load(f)
students_file = 'students.json'
with open(students_file) as file:
    student_new = json.load(file)

relocation_file = 'relocation.json'


for i in students_file:
    if "room" == id in rooms_file:
        with open(relocation_file) as fl:
            relocation_new = json.dump(relocation_file,'w')

What am i do wrong, help please. It returns nothing, but probably it should create a file "relocation.json" which contains list like that:

 [
{
  "id": 0,
  "name": "Room #0"
  "name": "Travis Tran",
  },
{
  "id": 1,
  "name": "Room #1"
  "name": "Brooke Ferrell",
  "name": "Ryan Keller",
  },

]
user20001
  • 15
  • 4
  • The output you have doesn't seem to match what you're attempting to do. Ryan Keller has a room value of 2 in the top part but then is in room 1 in the output. Is that desired? Please clean up your output file or be clearer on exactly what logic you're wanting. – jonyfries Feb 07 '20 at 18:44
  • sorry, now it's like it need to be – user20001 Feb 07 '20 at 18:48

1 Answers1

1

Can you try this below code and I think you expected answer shouldn't have same key names so I have renamed it to student_name as key(if required you can change name to room_name). I hope that should be fine for you as well.

import json

with open('files/rooms.json') as f:
    room_list = json.load(f)

with open('files/students.json') as file:
    student_list = json.load(file)


relocation_list = []

for student_dict in student_list:
    for room_dict in room_list:
        new_dict = {}
        if student_dict['room'] == room_dict['id']:
            new_dict["student_name"] = student_dict['name']
            new_dict.update(room_dict)
            relocation_list.append(new_dict)

with open('relocation.json', 'w') as f:
    f.write(str(relocation_list))

print(relocation_list)

output:

[{'student_name': 'Ryan Keller', 'id': 2, 'name': 'Room #2'}, {'student_name': 'Brooke Ferrell', 'id': 1, 'name': 'Room #1'}, {'student_name': 'Travis Tran', 'id': 0, 'name': 'Room #0'}]

Using list comprehensive way:

import json

with open('files/rooms.json') as f:
    room_list = json.load(f)

with open('files/students.json') as file:
    student_list = json.load(file)

print([{**room_dict, "student_name": student_dict['name']} for room_dict in room_list for student_dict in student_list if student_dict['room'] == room_dict['id']])
# output
# [{'id': 0, 'name': 'Room #0', 'student_name': 'Travis Tran'}, {'id': 1, 'name': 'Room #1', 'student_name': 'Brooke Ferrell'}, {'id': 2, 'name': 'Room #2', 'student_name': 'Ryan Keller'}]

EDIT For new requirement mentioned in comments

  • Avoid duplicate Ids in relocation_list - Here we merge values of student_name to list of student
  • Sort list of dict by value - Ref: Check this link there are many other ways too
import json

with open('files/rooms.json') as f:
    room_list = json.load(f)

with open('files/students.json') as file:
    student_list = json.load(file)


relocation_list = []


# We arent considering about duplicate item as it is created by same loop
def check_room_id_in_relocation_list(id_to_check):
    is_exist, index, item = False, None, {}
    for index, item in enumerate(relocation_list):
        if id_to_check == item['id']:
            is_exist, index, item = True, index, item
    return is_exist, index, item


for student_dict in student_list:
    for room_dict in room_list:
        new_dict = {}
        if student_dict['room'] == room_dict['id']:
            is_room_exist, index, item = check_room_id_in_relocation_list(room_dict['id'])
            if is_room_exist:
                # To merge same ids
                # since it already exist so update list's item with new student_name
                # instead of new key we are assigning list of names to key "student_name" to 
                relocation_list[index]['student_name'] = [relocation_list[index]['student_name'], 'new nameeeee']
            else:
                new_dict["student_name"] = student_dict['name']
                new_dict.update(room_dict)
                relocation_list.append(new_dict)

print("student list:", student_list)
print("room list: ", room_list)
print("relocation_list:", sorted(relocation_list, key=lambda k: k['id']))
with open('relocation.json', 'w') as f:
    f.write(str(sorted(relocation_list, key=lambda k: k['id'])))

# output
# student list: [{'id': 0, 'name': 'Ryan Keller', 'room': 2}, {'id': 1, 'name': 'Brooke Ferrell', 'room': 1}, {'id': 2, 'name': 'Travis Tran', 'room': 0}, {'id': 3, 'name': 'New User', 'room': 2}]
# room list:  [{'id': 0, 'name': 'Room #0'}, {'id': 1, 'name': 'Room #1'}, {'id': 2, 'name': 'Room #2'}]
# relocation_list: [{'student_name': ['Travis Tran', 'new nameeeee'], 'id': 0, 'name': 'Room #0'}, {'student_name': 'Brooke Ferrell', 'id': 1, 'name': 'Room #1'}, {'student_name': 'Ryan Keller', 'id': 2, 'name': 'Room #2'}]
Shakeel
  • 1,869
  • 15
  • 23
  • I tried, and it output this: [{'id': 5, 'name': 'Room #5', 'student_name': 'Cassandra Wilson'}, {'id': 5, 'name': 'Room #5', 'student_name': 'Cassandra Wilson'}, – user20001 Feb 07 '20 at 19:48
  • i need to make that for 10000 students and 1000 rooms, but now im trying with 10 students and 10 rooms, it's more simple to try Ur code is good thanks for a help, but it works not so i expect) – user20001 Feb 07 '20 at 19:50
  • Sorry about that can you please check now ? I have corrected the code. – Shakeel Feb 07 '20 at 19:58
  • Thanks man, u help me so much, can i ask u for help me to make it sorted like from 1 to 10 by room id, and may be u know may for example students which leave in room 3 be in one dictionary, like [{'student_name': 'Ryan Keller', 'student_name': 'Brooke Ferrell','id': 0, 'name': 'Room #0'} – user20001 Feb 07 '20 at 20:05
  • Sure, so your first request is that you want final result(`relocation_list`) to be sorted by `room` number ? and the second part I dont understand completely can you explain again with another example so that I can quickly try now ? – Shakeel Feb 07 '20 at 20:13
  • yes, it should be sorted by room number and the second part is for example, we have 2 students { "id": 9984, "name": "Gregory Herring", "room": 260 }, { "id": 9985, "name": "Jamie Walker", "room": 260 }, they have the same room number so in relocation_list, can it look like: [{'student_name': 'Gregory Herring','student_name': 'Jamie Walker', 'id': 260, 'name': 'Room #260'}, for my opinion we shouldn't repeat member of the list, if it's exist – user20001 Feb 07 '20 at 20:18
  • so i expect to see this: [{'student_name': 'Gregory Herring','student_name': 'Jamie Walker', 'id': 260, 'name': 'Room #260'} exept of this: [{'student_name': 'Gregory Herring', 'id': 260, 'name': 'Room #260'} [{'student_name': 'Jamie Walker', 'id': 260, 'name': 'Room #260'} – user20001 Feb 07 '20 at 20:20
  • After the EDIT section has that new requirements that you mentioned in comment. Instead of appending same keys in dict(i.e, `{student_name:x, student_name: y}`) I have created list of names for `student_name`(Ex: `{student_name:[x, y]}`) because having same keys is not correct way. I hope it is fine for you. :-) – Shakeel Feb 08 '20 at 21:17