3

I have dictionary which contain list of dictionaries as below.

I want to swap all values of list of dictionary based on name.

Example: swap_function('Arvind','Jayesh') should swap other values like surname, fullname & email.

I have already tried a lot from other website's references but not able achieve my goal.

data = {
   "items":[
      {                 
         "name":"Arvind",
         "surname":"Patel",
         "fullname":"Arvind Patel",
         "email":"abc@xyx.com"        
      },
      {        
         "name":"Jayesh",
         "surname":"Patel",
         "fullname":"Jayesh Patel",
         "email":"Patel@gmail.com"
      },
      {        
         "name":"Krishna",
         "surname":"dave",
         "fullname":"Krishna dave",
         "email":"Krishna@xyz.com"
      },
      {        
         "name":"Aditya",
         "surname":"Patel",
         "fullname":"Aditya Patel",
         "email":"Aditya@abc.com"
      }

   ]
}

I have tried like below but after that I am out of ideas.

def name_swap(name1, name2):

   for key, item in data.items():
      first_dict = item[0]
      second_dict = item[1]
      third_dict = item[2]
      forth_dict = item[3]
      fifth_dict = item[4]
after name_swap('Arvind', 'Krishna')

output : 
data = {
   "items":[
      {                 
         "name":"Arvind",
         "surname":"dave",
         "fullname":"Krishna dave",
         "email":"Krishna@xyz.com"        
      },
      {        
         "name":"Jayesh",
         "surname":"Patel",
         "fullname":"Jayesh Patel",
         "email":"Patel@gmail.com"
      },
      {        
         "name":"Krishna",
         "surname":"Patel",
         "fullname":"Arvind Patel",
         "email":"abc@xyx.com"
      },
      {        
         "name":"Aditya",
         "surname":"Patel",
         "fullname":"Aditya Patel",
         "email":"Aditya@abc.com"
      }

   ]
}
pissall
  • 7,109
  • 2
  • 25
  • 45
Aditya
  • 557
  • 3
  • 13

3 Answers3

2

Try this code:

i = next(i for i,item in enumerate(data['items']) if item['name'] == 'Arvind')
j = next(i for i,item in enumerate(data['items']) if item['name'] == 'Krishna')
data['items'][i]['name'], data['items'][j]['name'] = 'Krishna', 'Arvind'

And gives:

{'items': [{'name': 'Arvind',
   'surname': 'dave',
   'fullname': 'Krishna dave',
   'email': 'Krishna@xyz.com'},
  {'name': 'Jayesh',
   'surname': 'Patel',
   'fullname': 'Jayesh Patel',
   'email': 'Patel@gmail.com'},
  {'name': 'Krishna',
   'surname': 'Patel',
   'fullname': 'Arvind Patel',
   'email': 'abc@xyx.com'},
  {'name': 'Aditya',
   'surname': 'Patel',
   'fullname': 'Aditya Patel',
   'email': 'Aditya@abc.com'}]}

Ok now let's generalize this example, with the following function:

def swap_dict_list(dict_list, val1, val2, target='name', block_target=True):   
    try:
        i = next(i for i,item in enumerate(dict_list) if item[target] == val1)
        j = next(i for i,item in enumerate(dict_list) if item[target] == val2)
    except StopIteration:
        return dict_list
    dict_list[i], dict_list[j] = dict_list[j], dict_list[i]
    if block_target:
        dict_list[i][target], dict_list[j][target] = val1, val2
    return dict_list

In your case, you will use the function in this:

data['items'] = swap_dict_list(data['items'], 'Arvind', 'Krishna', target='name', block_target=True)

And you will get the same result shown above.

Code explenation

The swap_dict_list function receives as input the list of dictionaries 'dict_list', the 2 values ​​to search ('val1' and 'val2') and the dictionary key on which to perform the target search.

The function finds the indexes corresponding to the two values ​​searched for, and if they both exist it performs the swap. If block_target is True, the target values ​​are not exchanged.

The search is effected efficiently using generator expression.

Massifox
  • 4,369
  • 11
  • 31
  • Thanks for your effort but still I am not getting expeceted output. above code switching position of dictionaries but I want to swap other values keeping name there. – Aditya Sep 27 '19 at 06:58
  • add this line data['items'][i]['name'], data['items'][j]['name'] = 'Arvind', 'Jayesh' – Massifox Sep 27 '19 at 07:04
  • as you can see in my queustion I have written that after name_swap('Arvind', 'Krishna') , I have kept expected output also I want exact output keeping same order of internal dictionaries. – Aditya Sep 27 '19 at 07:29
  • Awesome ! Working ! – Aditya Sep 27 '19 at 08:16
0

If i got you right:

First you want to find the indexes of the two dicts:

Find the index of a dict within a list, by matching the dict's value

then switch positions of the items:

How to switch position of two items in a Python list?

def switch(list,name1, name2):
     index1 = next((index for (index, d) in enumerate(list) if d["name"] == name1), None)
     index2 = next((index for (index, d) in enumerate(list) if d["name"] == name2), None)
     list[index1]['name'], list[index2]['name'] = list[index2]['name'], list[index1]['name']
     return list

data['items'] = switch(data['items'], 'Arvind', 'Krishna')
TVK
  • 1,042
  • 7
  • 21
  • above code swap all values but I want to keep name & swap other values. – Aditya Sep 27 '19 at 06:47
  • Ok i edited my code to only switch names in the dicts and not the whole dicts – TVK Sep 27 '19 at 06:56
  • I am getting data['items'] = None when run above code. – Aditya Sep 27 '19 at 07:01
  • Your code working except problem is I want to keep name as on original index & want to swap other values. Your code swapping name which I do not want to do . I am trying to update your code as per my expectation. – Aditya Sep 27 '19 at 07:16
0

Try this :

def switch(list, name1, name2):
    for item in list:
        if item['name'] == name1:
            item['name'] = name2
        elif item['name'] == name1:
            item['name'] = name2

    return list


data = {
   "items":[
      {
         "name":"Arvind",
         "surname":"Patel",
         "fullname":"Arvind Patel",
         "email":"abc@xyx.com"
      },
      {
         "name":"Jayesh",
         "surname":"Patel",
         "fullname":"Jayesh Patel",
         "email":"Patel@gmail.com"
      },
      {
         "name":"Krishna",
         "surname":"dave",
         "fullname":"Krishna dave",
         "email":"Krishna@xyz.com"
      },
      {
         "name":"Aditya",
         "surname":"Patel",
         "fullname":"Aditya Patel",
         "email":"Aditya@abc.com"
      }

   ]
}

data['items'] = switch(data['items'], 'Arvind', 'Jayesh')

print data
Harsh Bafna
  • 2,094
  • 1
  • 11
  • 21