Search code examples
pythonappenditerable

Checking if value is present in the list of key-value pairs, if not present then add the new key-pair value from iterables (not overwriting same key)


If I used the not in it still appends the new key-pair value even if a specific value is already in the list.

    dict1 = {'a': 0, 'a': 5, 'b': 1, 'c': 2}
    list1 = [{'a': 0}] # This key-pair value is already in the list1 but 
                       # still added from dict1.

    new1 = []
    new2 = []
    for key, value in dict1.items():
        if value not in list1:
            new1.append(key)
            new2.append(value)

    new0 = {new1[i]: new2[i] for i in range(len(new1))}
    list1.append(new0)
    

Desired output is:

    list1 = [{'a': 0, 'a': 5, 'b': 1, 'c': 2}]

(As I dont want to overwrite the key/s)


Solution

  • As you do not provide example data, I have to make some guesses here. If I guessed incorrectly, please provide the required information.

    You call .items on list1. A list does not have a items function. Instead, I suspect your list1 is actually a dictionary, which would like this for example:

    list1 = {
        "a":1, 
        "b":2,
        "c":3
    }
    

    In your current loop, you check if the value is within list2. If list2 is actually a list, you're doing so correctly. However, based on your title I assume what you actually want to do is check if the key is in list2, and if not add the key:value to list2. You could not add a key:value pair to a list, so I assume that list2 shoudl also be a dictionary. You would be able to add them add as a tuple, but based on the title I assume that is not what you want.

    If you actually want to add it as a key:value pair to a dictionary, you could do that as follows:

    list2 = {}
    for key, value in list1.items():
        if key not in list2.keys(): # check if this key already exists
            list2[key] = value # if not, add they key with the value
    

    As list1 and list2 are not actually instances of list, but of dict I would recommend renaming your variables to avoid future confusion. Hope that helps!

    EDIT after update in question

    Your example data had a small mistake, as there were two a keys, meaning that the first {'a':0} would be overwritten within dict1 already.

    dict1 = {'a': 0, 'b': 5, 'c': 1, 'd': 2}
    list1 = [{'a': 0}] 
    

    As I understand it, you wish to check if the value is already containted within a list of dictionaries. As such, we need to get all the values from these dictionaries.

    As you do not want to overwrite any keys, it would need to be a list of dictionaries that each only have one key. As such, we can get each individual dictionary, get the keys. This returns an dict_keys object, which we can convert to a list. Since each dictionary within list1 always only has one key, we can just take the first from said lsit.

    [list(x.values())[0] for x in list1]
    

    Putting that within the loop we get

    for key, value in dict1.items():
        if not value in [list(x.values())[0] for x in list1]:
        # If no dictionary exists within `list1` with this value
            list1.append({key:value}) # then add it as a new dictionary
    

    This would return

    [{'a': 0}, {'b': 5}, {'c': 1}, {'d': 2}]
    

    You could run this code again with a different dict1 and it would not overwrite keys within list1, for example with:

    dict1 = {'a': 9}
    

    the output would become

    [{'a': 0}, {'b': 5}, {'c': 1}, {'d': 2}, {'a': 9}]