e hink27
e hink27

Reputation: 3

Replace text in a list of dictionaries

I have the following sample list of dictionaries and I would like to replace any . in the dictionary with a _, so the list would look like the list below.

I tried using replace but get the following error:

dict object has no attribute 'replace'

if I try something like this:

orig = [
    {
        "health": "good",
        "status": "up",
        "date": "2022.03.10",
        "device.id": "device01"
    },
    {
        "health": "poor",
        "status": "down", 
        "date": "2022.03.10",
        "device.id": "device02"
    }
]
    
length = len(orig)
for i in range(length):
    orig[i].replace(".", "_")

Current list:

[
    {
        "health": "good",
        "status": "up",
        "date": "2022.03.10",
        "device.id": "device01"
    },
    {
        "health": "poor",
        "status": "down",
        "date": "2022.03.10",
        "device.id": "device02"
     }
]

The new list should look like this:

[
    {
        "health": "good",
        "status": "up",
        "date": "2022_03_10",
        "device_id": "device01"
     },
     {
        "health": "poor",
        "status": "down",
        "date": "2022_03_10",
        "device_id": "device02"
     }
]

Upvotes: 0

Views: 2227

Answers (5)

JonSG
JonSG

Reputation: 13067

The answer by @CryptoFool seems like the one you want. A slightly more blunt force answer might be to just work with strings.

import json
orig= [
    {"health": "good", "status": "up", "date":"2022.03.10","device.id":"device01"},
    {"health": "poor", "status": "down", "date":"2022.03.10","device.id":"device02"}
]
orig_new = json.loads(json.dumps(orig).replace(".","_"))
print(orig_new)

That will give you :

[
    {'health': 'good', 'status': 'up', 'date': '2022_03_10', 'device_id': 'device01'},
    {'health': 'poor', 'status': 'down', 'date': '2022_03_10', 'device_id': 'device02'}
]

Upvotes: 2

Ji Bin
Ji Bin

Reputation: 531

Try this:

orig = list(map(lambda item: dict((k.replace('.', '_'), v.replace('.', '_')) for k, v in item.items()), orig))

The output should be your want.

  • Basically, the original data is a list of dict, and the target is to normalize(replace . -> _) each key and value in the dict.
  • So the inner transformation is using a dict() to produce a new dict from the original one, dict((k.replace('.', '_'), v.replace('.', '_')) for k, v in item.items())
  • And for the outer part is a pythonic map operation for iterating a list

Actually, @CryptoFool's answer should be more clear for beginners.

Upvotes: 2

Mahsirat
Mahsirat

Reputation: 79

you need to iterate in list of dictionaries or change format:

# first solution
new_list_of_dictionaries = []
for dictionary in orig:
    new_dictionary = {}
    for k, v in dictionary.items():
        new_dictionary[k.replace(".", "_")] = v.replace(".", "_")
    new_list_of_dictionaries.append(new_dictionary)
orig = new_list_of_dictionaries
# second_solution
import json
orig = json.loads(json.dumps(orig).replace(".", "_"))

Upvotes: 0

CryptoFool
CryptoFool

Reputation: 23079

I don't understand how what you're trying would even run. For the line orig[i].replace(".", "_"), orig[i] will be a dict, and since a dict has no replace() method, you'll get an error trying to execute this line.

You need to be working on additional level down, operating on each of the key/value pairs in each dict. Here's one solution:

orig= [{"health": "good", "status": "up", "date":"2022.03.10","device.id":"device01"}, {"health": "poor", "status": "down", "date":"2022.03.10","device.id":"device02"}]

result = []
for inner_dict in orig:
    new_inner = {}
    for k, v in inner_dict.items():
        new_inner[k.replace('.', '_')] = v.replace('.', '_')
    result.append(new_inner)

print(result)

If the keys didn't need to change, it would be simpler (see the other two answers that don't get it right). You then wouldn't have to create a new structure, but could just work on the values within the existing structure. But since the keys will also change, it's easiest just to build a new result from scratch, like this shows.

Result:

[{'health': 'good', 'status': 'up', 'date': '2022_03_10', 'device_id': 'device01'}, {'health': 'poor', 'status': 'down', 'date': '2022_03_10', 'device_id': 'device02'}]

Upvotes: 2

wLui155
wLui155

Reputation: 742

The following seems to do the trick:

def convert(list_dict, old_text, new_text):
    def replace_dict(old_dict, old_text, new_text):
        return {key.replace(old_text, new_text) : val.replace(old_text, new_text) for key, val in old_dict.items()}
        
    for i in range(len(list_dict)):
        list_dict[i] = replace_dict(list_dict[i], old_text, new_text)

orig= [{"health": "good", "status": "up", "date":"2022.03.10","device.id":"device01"}, {"health": "poor", "status": "down", "date":"2022.03.10","device.id":"device02"}]

convert(orig, '.', '-')
print(orig)

Basically, it modifies the old dictionary in-place but creates replacement dictionaries for each element.

Upvotes: 0

Related Questions