3

I have a question. I tried to put together information from other questions but with no success. Assume I have data in the following format:

file_list = ["f1", "f2", "f3"]
inner_dict = {1: "one", 2: "two", 3: "three"}
outer_dict = {}

for f in file_list:
     outer_dict[f] = inner_dict

My aim is to print (to be saved into a file) in the following way:

f1, 1, one
f1, 2, two
f1, 3, three
f2, 1, one
f2, 2, two
f2, 3, three
f3, 1, one
f3, 2, two
f3, 3, three

To this aim, I started focusing on the items of outer_dict, and I managed to print them separately, but I am not sure how to further join (and, more importantly, if this is the most direct way to go).

for key, value in outer_dict.items():
    inn_keys = value.keys()
    inn_values = value.values()
    b1 = "\n".join([str(x) for x in inn_keys] )
    b2 = "\n".join([str(x) for x in inn_values] )

Thanks for any suggestions.

midori
  • 4,459
  • 5
  • 26
  • 57
Stefano Lombardi
  • 1,461
  • 1
  • 20
  • 46

6 Answers6

2

You can do this:

string_list = []

for el1 in file_list:
    for el2 in inner_dict.items():
        string_list.append(", ".join([el1, str(el2[0]), el2[1]]))

print(string_list)

Output:

['f1, 1, one', 
 'f1, 2, two', 
 'f1, 3, three', 
 'f2, 1, one', 
 'f2, 2, two', 
 'f2, 3, three', 
 'f3, 1, one', 
 'f3, 2, two',
 'f3, 3, three']
Mohammed Aouf Zouag
  • 16,366
  • 3
  • 36
  • 64
2

Patching your code to work will look something like this:

b1 = ""
for key, value in outer_dict.items():
    b1 += "\n".join([','.join([key,str(k),v]) for k, v in value.items()]) + '\n'

But, I think you did it way more complicated than it should be in python, a much simpler solution will be using nested loops:

s = ""
for f in file_list:
    for k,v in inner_dict.items():
        s+= ','.join([f,str(k),v]) + "\n"

I'm sure you can figure out a one-liner that will do this for you.

eli
  • 481
  • 1
  • 3
  • 21
1

Double join can be used in your case, remember to convert your ints to str:

print '\n'.join([', '.join([e1] + [str(e) for e in e2]) for e1, e2 in zip(file_list, inner_dict.items())])

f1, 1, one
f2, 2, two
f3, 3, three
midori
  • 4,459
  • 5
  • 26
  • 57
0

What about this oneliner- just concatenate tuples (i.e. [(i,)+j for j in inner_dict.items() for i in file_list]) and flatten the list of tuples into a simple list.

[item for sublist in [(i,)+j for j in inner_dict.items() for i in file_list] for item in sublist]

Output-

['f1', 1, 'one', 'f2', 1, 'one', 'f3', 1, 'one', 'f1', 2, 'two', 'f2', 2, 'two', 'f3', 2, 'two', 'f1', 3, 'three', 'f2', 3, 'three', 'f3', 3, 'three']

N.B. Better to use OrderedDict in case of maintaining order using dictionary.

SIslam
  • 4,986
  • 1
  • 21
  • 31
0

Seems like the other answers assume a deterministic order in the dictionary. But dictionaries do not have a deterministic order. In fact, you can set hash_randomization in Python 2. Just start with the command line option -R:

python -R

This is the default in Python 3.

So to make this work more reliably and also with Python 3, sort the keys of the inner dictionary. Since it is used many times, sort it only once and re-use it in all iterations over the file list:

from __future__ import print_function

file_list = ["f1", "f2", "f3"]
inner_dict = {1: "one", 2: "two", 3: "three"}

inner_list = [', '.join([str(key), inner_dict[key]]) for key in sorted(inner_dict)]

for fname in file_list:
    for inner in inner_list:
        print('{}, {}'.format(fname, inner))

Output:

f1, 1, one
f1, 2, two
f1, 3, three
f2, 1, one
f2, 2, two
f2, 3, three
f3, 1, one
f3, 2, two
f3, 3, three
Community
  • 1
  • 1
Mike Müller
  • 71,943
  • 15
  • 139
  • 140
0

Since you wanted to save it to a csv file, see if this helps. You can use OrderedDict if the order matters.

from collections import OrderedDict
import csv


file_list = ["f1", "f2", "f3"]
inner_dict = {1: "one", 2: "two", 3: "three"}
outer_dict = OrderedDict()

for f in file_list:
    outer_dict[f] = inner_dict

rows = []
for i,k in outer_dict.items():
    for m,n in k.items():
        rows += [[str(x) for x in [i, m, n]]]

with open('test.csv', 'w') as f:
    _csv = csv.writer(f, escapechar=' ', quoting=csv.QUOTE_NONE)
    [_csv.writerow(row) for row in rows]

The test.csv file would look so:

f1,1,one
f1,2,two
f1,3,three
f2,1,one
f2,2,two
f2,3,three
f3,1,one
f3,2,two
f3,3,three
harishkb
  • 366
  • 2
  • 7