How can lists in a list be overwritten by new lists in a new list in Python?

85 Views Asked by At

If someone knows how to phrase the question to make it clearer, feel free to edit it!

I have a list like this:

a = [["Adolf", "10"], ["Hermann", "20"], ["Heinrich", "30"]]

and I have an 'update' list like this:

b = [["Rudolf", "40"], ["Adolf", "50"]]

I want to be able to add new entries and overwrite identical entries in list a using list b:

c = magic(a, b)

The result should be as follows:

>>> print(c)
[["Adolf", "50"], ["Hermann", "20"], ["Heinrich", "30"], ["Rudolf", "40"]]

Is there a function like magic in existence? If not, how could it be written?


EDIT: Just to be clear, I am aware of the dictionary approach. For my purposes, I need to have duplicate entries, so dictionaries are not appropriate -- that's why I asked about lists. Before it is mentioned, there'll be protections for these special duplicate entries. For example, let's say "Heinrich" is one of these special types of entry that can have duplicates:

a = [['Adolf', '10'], ['Hermann', '20'], ['Heinrich', '30'], ['Heinrich', '15']]

Now, let's say I have the update list as the following:

b = [['Rudolf', '40'], ['Adolf', '50']]

Updating list a with list b should result in the following list:

>>> print(c)
[['Adolf', '50'], ['Hermann', '20'], ['Heinrich', '30'], ['Heinrich', '15'], ['Rudolf', '40']]

As you can see, there are intended duplicate entries. This is why a dictionary cannot be used directly.

4

There are 4 best solutions below

1
On BEST ANSWER

You should probably be using a dictionary for this. You're essentially mimicking its functionality anyway. If you have a dictionary a and dict b:

a = { "Adolf": "10", "Hermann": "20", "Heinrich": "30" }
b = { "Rudolf": "40", "Adolf": "50" }

then you can just do as follows:

a.update(b)

One line! Easy as pie. And that's as close as you're going to come to a built-in magic(), I think. But if you needed to do this with only lists, without ever using a dictionary (because I can't imagine why it'd be okay to use a dictionary as an intermediate step, but not store your data in one), you could do it as follows:

def magic(original, update):
    for i in range(len(update)):
        found_match = False

        for j in range(len(original)):
            # if there's a matching 'key' in an index of the original list
            if update[i][0] == original[j][0]:
                found_match = True
                original[j][1] = update[i][1]

        # if there's no entry to override, place a new entry in
        if not found_match:
            original.append(update[i])

Again, though, unless you've got some super weird use case, I can't imagine why this is preferable collections- or performance-wise over a dictionary.

1
On
  1. Convert a to a dictionary
  2. Call the update method on a with a dictionary full of b as the argument
  3. Get a list of the items in the updated version of a

Here's an example:

adict = dict(a)
adict.update(dict(b))
[list(item) for item in adict.iteritems()]
1
On
>>> a = [["Adolf", "10"], ["Hermann", "20"], ["Heinrich", "30"]]
>>> b = [["Rudolf", "40"], ["Adolf", "50"]
>>> c = [list(i) for i in (dict(a+b).items())] # if b is update list then use (a+b), if you write (b+a) it will treat a as update list.
>>> c
[['Hermann', '20'], ['Rudolf', '40'], ['Adolf', '50'], ['Heinrich', '30']]
1
On

I recommend you using dictionary as they mentioned.

I assume you have given list a and b

def magic(a, b):
    d = dict(a)   # convert a to a dictionary
    d.update(b)   # value updates
    result = [ list(i) for i in d.iteritems() ]
    return result

The result is in the form you want