user3541631
user3541631

Reputation: 4008

For a dictionary compare both key and value with the values in a list

I have the following structures:

prev = { 'alpha:10.2': '145', 'teta:180': '198', 'eltira:140': '222', 'ronta:23.14':220}
now = ['alpha:10.3','teta:180', 'eltira:142']

and the following code:

   old = []
    for k, v in prev.iteritems():
     if k not in now:
       old.append(v)

So if the key from the dict prev is not found in the list now, I add the value to the old list.

Result 'old= [ '145', '222']`

But, I want to check also which part doesn't correspond from the key. I'm inclined to use namedtuple.

Package = collections.namedtuple('Package', 'name version')

for k, v in prev.items():
  name, version = k.split(':')
  Package(name=k, version='v')
  1. if the name corresponds but the version not, do the same as above.
  2. if the name is not found add it to a new list old_names, but also do as above.

The issue is that if k not in now will not work. I can do it with two loops and three ifs but maybe there is an option to do it more clean.

Expecting output:

old=[ '145', '222'] old_names=['ronta']

Upvotes: 1

Views: 59

Answers (3)

Jab
Jab

Reputation: 27515

You can make now a dict by maping operator.methodcaller to it and wrapping it in dict() then a comprehension will be easy using the same method on prev:

splitter = operator.methodcaller('split', ':')
now_dict, kv_map = dict(map(splitter, now)), map(splitter, prev)

old = [prev[':'.join((k,v))] for k, v in kv_map if k in now_dict]
old_names = [n for n, v in kv_map if n not in now_dict]

Results:

#old
['145', '198', '222']
#old_names
[]

Upvotes: 0

Florian Bernard
Florian Bernard

Reputation: 2569

Here is a way to do it:

prev = { 'alpha:10.2': '145', 'teta:180': '198', 'eltira:140': '222', 'zeta:12.1' : '334'}
now = ['alpha:10.3','teta:180', 'eltira:142']

now_splited = [nk.split(":") for nk in now]

old = []
old_name = []
for k, v in prev.items():
    if k not in new_key:
        old_n, old_v = k.split(":")
        name = any(map(lambda n : n[0] == old_n, now_splited))
        version = any(map(lambda n : n[1] == old_v, now_splited))
        if name and not version:
            old.append(v)
        elif not name:
            old_name.append(old_n
            old.append(old_v))

Results :

>>> print(old, old_name)
['145', '222', '334'] ['zeta']

Upvotes: 0

Vivek Khimani
Vivek Khimani

Reputation: 75

I have splitted the 'now' list and converted it to a dictionary (name:version) which takes a single iteration. Later, the values from the dictionary can be accessed in constant time for further operations.

prev = { 'alpha:10.2': '145', 'teta:180': '198', 'eltira:140': '222', 'old:1. 43':'150'}
now = ['alpha:10.3','teta:180', 'eltira:142']

now_dict = {}
old = []
old_names = []

for items in now:
  temp0,temp1 = items.split(':')
  now_dict[temp0] = temp1

for k,v in prev.items():
   name,version = k.split(':')
   if name not in now_dict.keys():
      old_names.append(name)
      old.append(v)
      continue

   if version != now_dict[name]:
      old.append(v)
      continue

   else:
     continue

if __name__ == '__main__':
  print(old_names)
  print(old)

Upvotes: 1

Related Questions