Reputation: 143
I have a dictionary of the form dict[keyA][key1] where 'key1' is a dictionary of lists. i.e., keyA is a dictionary of dictionaries of lists. Below is a sample of how the dictionary could be created.
dict = { 'keyA': { 'keyA1': ['L1','L2',...], 'keyA2': ['L','L',...], ... },
'keyB': { 'keyB1': ['L1','L2',...], 'key...': ['L','L',..], ...}
}
I need to join the values of the lists together and would like to do this with a construct like:
newStr = ' A B C '.join(val for val in (dict[keyA][k] for k in dict[keyA]))
This fails with an error that val is a 'list' vs. a string.
when I resolve val via 2 for loops I get a list of strings as I would expect the above to provide.
Simple example that works for a one entry in the outer dictionary and prints a list of strings
for k in dict[keyA]:
for val in dict[keyA][k]:
print(val)
Example that does not work and prints a 'list':
for val in (dict[keyA][k] for k in dict[keyA]): print(val)
output from failing test above (note the enclosing brackets in the output). If I 'type' this value, it indicates that the value is indeed a list: ['some text', 'some more text', ....]
The working nested 'for' loops above produces the above text on separate lines without the brackets as expected, the output of which should work in the join to give the desired results....
Can anyone explain what I am missing here?
Upvotes: 0
Views: 42
Reputation: 1212
Your syntax for the "nested" comprehension isn't quite correct.
If you separate out the second portion, you'll see what's tripping it up:
>>> [_dict['keyA'][k] for k in _dict['keyA']]
[['L1', 'L2', 'L3'], ['Q1', 'Q2', 'Q3']]
The order for a nested comprehension isn't intuitive (IMO) and reads left-to-right in order of descending loops, instead of in an unrolling fashion which I think most people would initially assume.
In any case, you just need to adjust your comprehension:
>>> ' A B C '.join(val for key in _dict['keyA'] for val in _dict['keyA'][key])
'L1 A B C L2 A B C L3 A B C Q1 A B C Q2 A B C Q3'
Or using dict.items
:
(Note: _
is used as a placeholder/throwaway here, since you don't actually need the "key" loop variable in this case)
>>> ' A B C '.join(val for _, v in _dict['keyA'].items() for val in v)
'L1 A B C L2 A B C L3 A B C Q1 A B C Q2 A B C Q3'
Also, as an aside, avoid using python built-ins as variable names, or you won't be able to use that built-in later on in your code.
Upvotes: 1