aysh
aysh

Reputation: 599

How to get the values before a key and after a key

I have dictionary below

{'1': {'Col1': 'Val1', 'Col2': 'Val2', 'output': 'Out1'},
 '2': {'Col1': 'Val1', 'Col2': 'Val2', 'output': 'Out1'},
 '3': {'Col1': 'Val1', 'Col2': 'Val2', 'output': 'Out1'},
 '4': {'Col1': 'Val1', 'Col2': 'Val2', 'output': 'Out1'}}

I need to get the values before the key output

since dictionary is unordered i have converted into below

              OrderedDict([('1',
              OrderedDict([('Col1', 'Val1'),
                           ('Col2', 'Val2'),
                           ('output', 'Out1')])),
             ('2',
              OrderedDict([('Col1', 'Val1'),
                           ('Col2', 'Val2'),
                           ('output', 'Out1')])),
             ('3',
              OrderedDict([('Col1', 'Val1'),
                           ('Col2', 'Val2'),
                           ('output', 'Out1')])),
             ('4',
              OrderedDict([('Col1', 'Val1'),
                           ('Col2', 'Val2'),
                           ('output', 'Out1')]))])

Expected out is below, need to extract the values before output

{'1': ['Val1', 'Val2'],
'2': ['Val1', 'Val2'],
'3': ['Val1', 'Val2'],
'4': ['Val1', 'Val2']}

Expected out is below, need to extract the values after the output key

{'1': [],
'2': [],
'3': [],
'4': []}

Sample dictionary for testing

{'1': {'Col1': 'Val1', 'output': 'Out1', 'test': 'Out1'},
 '2': {'Col1': 'Val1', 'output': 'Out1', 'test': 'Out1'},
 '3': {'Col1': 'Val1','output': 'Out1'},
 '4': {'Col1': 'Val1', 'output': 'Out1'}}

Expected out is below, need to extract the values before output

{'1': ['Val1'],
'2': ['Val1'],
'3': ['Val1'],
'4': ['Val1']}

Expected out is below, need to extract the values after the output key

{'1': ['Out1'],
'2': ['Out1'],
'3': [],
'4': []}

Upvotes: -1

Views: 73

Answers (2)

alani
alani

Reputation: 13079

You can iterate over items using an iterator and appending to before list. When the key you are looking for is found, break from that loop and then iterate again using that same iterator to read the values for the after list.

from collections import OrderedDict

d = OrderedDict([('1',
                  OrderedDict([('Col1', 'Val1'),
                               ('Col2', 'Val2'),
                               ('output', 'Out1')])),
                 ('2',
                  OrderedDict([('Col1', 'Val1'),
                               ('Col2', 'Val2'),
                               ('output', 'Out1')])),
                 ('3',
                  OrderedDict([('Col1', 'Val1'),
                               ('Col2', 'Val2'),
                               ('output', 'Out1')])),
                 ('4',
                  OrderedDict([('Col1', 'Val1'),
                               ('Col2', 'Val2'),
                               ('output', 'Out1')]))])

def vals_before_and_after(od, key):
    it = iter(od.items())
    before_vals = []
    for k, v in it:
        if k == key:
            break
        before_vals.append(v)
    after_vals = [v for k, v in it]
    return before_vals, after_vals

before = OrderedDict()
after = OrderedDict()
for k, v in d.items():
    before[k], after[k] = vals_before_and_after(v, 'output')

print(before)
print(after)

Gives:

OrderedDict([('1', ['Val1', 'Val2']), ('2', ['Val1', 'Val2']), ('3', ['Val1', 'Val2']), ('4', ['Val1', 'Val2'])])
OrderedDict([('1', []), ('2', []), ('3', []), ('4', [])])

You might also raise an exception if the key you are looking for is never found (break never executed). For example:

    ...
    for k, v in it:
        if k == key:
            break
        before_vals.append(v)
    else:
        raise RuntimeError(f'The key {key} was not found')
    ...

Upvotes: 2

YOLO
YOLO

Reputation: 21719

You can use dict comprehension:

dx = {k: list({i:x for i, x in v.items() if x != 'Out1'}.values()) for k,v in d.items()}

print(dx)

{'1': ['Val1', 'Val2'],
 '2': ['Val1', 'Val2'],
 '3': ['Val1', 'Val2'],
 '4': ['Val1', 'Val2']}

Upvotes: 1

Related Questions