0

I have a dictionary -

d={'revenues':
             {
              '201907':
                      {'aaa.csv':'fdwe34x2'},
              '201906':{'ddd.csv':'e4c5q'}
             },    
   'complaints':
             {'2014':
                    {'sfdwa.csv','c2c2jh'}
             }
  }

I want to convert it into list of tuples -

[
 ('revenues','201907','aaa.csv','fdwe34x2'),
 ('revenues','201906','ddd.csv','e4c5q'),
 ('complaints','2014','sfdwa.csv','c2c2jh')
]

I tried using list comprehensions, but did not help -

l = [(k,[(p,q) for p,q in v.items()]) for k,v in d.items()]
print(l)
    [('revenues', [('201907', {'aaa.csv': 'fdwe34x2'}), ('201906', {'ddd.csv': 'e4c5q'})]),
     ('complaints', [('2014', {'c2c2jh', 'sfdwa.csv'})])]

Any suggestions?

cph_sto
  • 7,189
  • 12
  • 42
  • 78
  • is this `{'sfdwa.csv','c2c2jh'}` stored as set intentionally or just a typo? – RomanPerekhrest Aug 23 '19 at 13:53
  • Why did the code provided not work as planned? – MAO3J1m0Op Aug 23 '19 at 13:53
  • No, there is no typo. I just tried to indent it for easy read. – cph_sto Aug 23 '19 at 13:55
  • @cph_sto..I hope you are doing well. Could you please take a look at below question and share your suggestions. also if possible convert that scala code into pyspark. https://stackoverflow.com/questions/57918129/parsing-a-csv-file-in-pyspark-using-spark-inbuilt-functions-or-methods – vikrant rana Sep 13 '19 at 21:11
  • 1
    @vikrantrana Hi Vikrant. I am good and I hope that all at well at your end. I will be on my work station on Monday and then would have a deep look at it. – cph_sto Sep 14 '19 at 12:01

3 Answers3

4

If you're not sure how many levels this list may have, it seems that what you need is recursion:

def unnest(d, keys=[]):
    result = []
    for k, v in d.items():
        if isinstance(v, dict):
            result.extend(unnest(v, keys + [k]))
        else:
            result.append(tuple(keys + [k, v]))
    return result

Just a friendly reminder: before Python 3.6, dict order is not maintained.

[('complaints', '2014', 'sfdwa.csv', 'c2c2jh'),
 ('revenues', '201906', 'ddd.csv', 'e4c5q'),
 ('revenues', '201907', 'aaa.csv', 'fdwe34x2')]
augustomen
  • 8,977
  • 3
  • 43
  • 63
1

You can loop through the levels of your dictionary:

[(x, y, z) for x in d for y in d[x] for z in d[x][y]]
busybear
  • 10,194
  • 1
  • 25
  • 42
0

You can do it using a list comprehension, but it would be quite complex, and not easy to maintain if the structure changes. Unless you especially need good performance, I would suggest using a generic recursive function:

def unnest(d, keys=[]):
    result = []
    if isinstance(d, dict):
        for k, v in d.items():
            result.extend(unnest(v, keys + [k]))
    elif isinstance(d, list):
        result.append(tuple(keys + d))
    elif isinstance(d, set) or isinstance(d, tuple):
        result.append(tuple(keys + list(d)))
    else:
        result.append(tuple(keys + [d]))
    return result

As a bonus, I've also supported lists and tuples during the recursion, in addition to the set on the provided example.

Amir B
  • 1