skip to Main Content

I would like to replace ID’s which for now contain numbers and letters with unique ID which contains only numbers.

Id’s now:

    "Id": "a4555752s"
    "SummaryId": "a4555752s"
    "Id": "a4asa85"
    "Id": "a4ddd244"

Second thing is that ID can be repeated in case if there are other items which belong to it and that would have to be changed together with specific ID if this is exact the same value like here.

"Id": "a4555752s"
"SummaryId": "a4555752s"

I wrote some code, but this is not very efficient since it is replacing all id’s with one unique id.

Code:

    import json
    import random
    number = random.randint(1000,1000000)
    
    
    a = '''
{
  "people": [
    {
      "Name": "Jan",
      "Lastname": "Szewc",
      "Id": "174167"
    },
    {
      "Name": "Marek",
      "Lastname": "Piorun",
      "Id": "764120"
    },
    {
      "Name": "Mikolaj",
      "Lastname": "Ciekasz",
      "Id": "43409",
      "ManagerId": "a4555752s",
      "CoworkersId": [
        "1278978",
        "a4555752s"
      ]
    }
  ]
}
    '''
    data = json.loads(a)
    i = 0
    for item in (data["people"]):
        item["Id"] = item["Id"].replace(item["Id"], str(number))
    print(data["people"])

results:

[{'Name': 'Jan', 'Lastname': 'Szewc', 'Id': '853251'}, {'Name': 'Marek', 'Lastname': 'Piorun', 'Id': '853251'}, {'Name': 'Mikolaj', 'Lastname': 'Ciekasz', 'Id': '853251', 'SummaryId': 'a4555752s'}]

Can you give me some tips?

3

Answers


  1. You need to use generate the random number in the loop, and don’t use str.replace when replacing the whole value, just erase it

    for item in data["people"]:
        item["Id"] = random.randint(1000, 1000000)
    
    Login or Signup to reply.
  2. in your case you havesometimes a key : SummaryId with this cod we can change both of them in that key exist and also you need this random number be a string right ?

    for item in data["people"]:
        randonm_int = str(random.randint(1000, 1000000))
        item["Id"] = random_int
        try :
            item['SummaryId'] = random_int
    
        except KeyError:
            pass
    
    Login or Signup to reply.
  3. If I understand you correctly, you want to cache generated keys, so that if they are referred to later in the iterations, you can use the same Id to refer to another object.

    There are built-in versions of caches, such as functools.cache. However, this is how I would solve the problem without using that decorator:

    import json
    import random
    
    class Cache:
        # A dictionary that keeps a record of "seen" keys
        key_cache = {}
    
        @classmethod
        def generate_replacement_key(cls, key: str) -> str:
            """
                If key has already been seen, then return the cached key for that, 
                otherwise generate and store a new key.
            """
            new_key = cls.key_cache.setdefault(key, cls.generate_random_key())
            return new_key
        
        @classmethod
        def generate_random_key(cls) -> str:
            """
                returns a random key, that hasn't been generated before
            """
            new_key = str(random.randint(1000, 1000000))
            if new_key in cls.key_cache.values():
                return cls.generate_random_key()
            return new_key
    
    a = '''
    {
      "people": [
        {
          "Name": "Jan",
          "Lastname": "Szewc",
          "Id": "a4555752s"
        },
        {
          "Name": "Marek",
          "Lastname": "Piorun",
          "Id": "a4asa85"
        },
        {
          "Name": "Mikolaj",
          "Lastname": "Ciekasz",
          "Id": "a4ddd244",
          "SummaryId": "a4555752s",
          "CoworkersId": [
            "1278978",
            "a4555752s"
          ]
        }
      ]
    }
    '''
    data = json.loads(a)
    for people in data["people"]:
        # use walrus operator to make less boilerplate-code.
        if (id_string := people.get("Id")): # use dict.get to avoid key-errors.
            people["Id"] = Cache.generate_replacement_key(id_string)
        if (summary_id_string := people.get("SummaryId")):
            people["SummaryId"] = Cache.generate_replacement_key(summary_id_string)
        # If the object contains a coworker_list, then we want to loop 
        # over each id in that list and replace them as well.
        if (coworkersId_list := people.get("CoworkersId")):
            for idx, coworker_id in enumerate(coworkersId_list):
                coworkersId_list[idx] = Cache.generate_replacement_key(coworker_id)
    
    print(json.dumps(data, indent=2))
    

    And a sample output:

    {
      "people": [
        {
          "Name": "Jan",
          "Lastname": "Szewc",
          "Id": "363988"
        },
        {
          "Name": "Marek",
          "Lastname": "Piorun",
          "Id": "381586"
        },
        {
          "Name": "Mikolaj",
          "Lastname": "Ciekasz",
          "Id": "736870",
          "SummaryId": "363988",
          "CoworkersId": [
            "888351",
            "363988"
          ]
        }
      ]
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search