Python Forum
complicated dict comprehension
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
complicated dict comprehension
#1
# Initial dictionary
d = {
    'one': 'some val',
    'two': 'some val',
    'three': {
        'subkey_1': 'some val',
        'subkey_2': 'some val'
        },
    'four': 'some val',
    'five': {
        'subkey_1': 'some val',
        'subkey_2': 'some val'
        },
    'six': 'some val'
}

# This results in the dictionary that I want:
new = {}
for k, v in d.items():
    if not isinstance(v, dict):
        new[k] = v
    else:
        for i, j in v.items():
            new['%s_%s' % (k, i)] = j
print(new)


# example correct output:
# {
#     'one': 'some val',
#     'two': 'some val',
#     'three_subkey_1': 'some val',
#     'three_subkey_2': 'some val',
#     'four': 'some val',
#     'five_subkey_1': 'some val',
#     'five_subkey_2': 'some val',
#     'six': 'some val'
# }


# But can this be done in a dict comprehension?
# I am trying this:

new = {k: v if not isinstance(v, dict) else {i['%s_%s' % (k, i)]: j for i, j in v.items()} for k, v in d.items()}
print(new)

# But I suspect that inner dictionary needs to be unpacked somehow? Is this possible? Maybe with another technique?
Reply
#2
Quote:>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.

Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Recommended Tutorials:
Reply
#3
The first version is better. I like "yield" and reusable functions so I would write this
d = {
    'one': 'some val',
    'two': 'some val',
    'three': {
        'subkey_1': 'some val',
        'subkey_2': 'some val'
        },
    'four': 'some val',
    'five': {
        'subkey_1': 'some val',
        'subkey_2': 'some val'
        },
    'six': 'some val'
}

def subitems(d):
    for key, value in d.items():
        if isinstance(value, dict):
            for subkey, subvalue in value.items():
                yield f"{key}_{subkey}", subvalue
        else:
            yield key, value
            
new = dict(subitems(d))
print(new)
metulburr likes this post
Reply
#4
Hmmm okay. I was wondering if possible to do the unreadable one-liner haha. Thanks
Reply
#5
You can do pretty much anything in one liners. Especially list ocmps in combination with the use of the semicolon to separate statements on one line. But the time it takes to make them and decipher them is not worth the hassle.
Recommended Tutorials:
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Complicated ComputerAstronaut 1 1,609 Dec-10-2020, 03:19 AM
Last Post: DT2000
  a complicated randomized function which I'm stuck on jojo77m 11 3,566 Aug-27-2020, 09:24 AM
Last Post: DPaul
  Sort a dict in dict cherry_cherry 4 77,234 Apr-08-2020, 12:25 PM
Last Post: perfringo
  dictionary: print key/value with list(dict) comprehension wardancer84 4 3,005 Nov-14-2018, 03:14 PM
Last Post: wardancer84
  Newbie question for complicated namedtuple generation zydjohn 0 2,182 Dec-16-2017, 09:50 AM
Last Post: zydjohn

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020