Python using format_map with dictionary

I have a dictionary:

People={
       'name':['john','peter'],
       'age':[56,64]
       }

      

Output

'My name is {name[0]},i am {age[0]} old'.format_map(People)

      

gives

'My name is john,i am 56 old'

      

I would like to use format_map in a loop to get:

'My name is {name[x]},i am {age[x]} old'

      

for each element in the dictionary, for example:

'My name is john,i am 56 old'
'My name is peter,i am 64 old'

      

but a loop like:

['My name is {name[x]},i am {age[x]} old'.format_map(People) for x in range(0,len(People['name']))]

      

gives:

KeyError: 'name'

      

+3


source to share


4 answers


str.format_map

takes a mapping. You cannot pass an additional argument.

Alternatively, you can use str.format

, but nesting {..}

inside indexing ( {0[name][{x}]}

) is not allowed.



A workaround using str.format

and zip

/ map

:

>>> people = {
...    'name': ['john','peter'],
...    'age': [56, 64]
... }

>>> ['My name is {}, i am {} old'.format(*x)
...  for x in zip(people['name'], people['age'])]
['My name is john, i am 56 old', 'My name is peter, i am 64 old']

>>> ['My name is {}, i am {} old'.format(*x)
...  for x in zip(*map(people.get, ['name', 'age']))]
['My name is john, i am 56 old', 'My name is peter, i am 64 old']

      

+2


source


You can do two-way formatting:

people = {
   'name': ['John', 'Peter'],
   'age': [56, 64]
}

for i in range(2):
    'My name is {{name[{0}]}}, I am {{age[{0}]}} years old.'.format(i).format_map(people)

#>>> 'My name is John, I am 56 years old.'
#>>> 'My name is Peter, I am 64 years old.'

      



...{{...}}...

formats before ...{...}...

, so the second call comes up format

.

+1


source


You might want to consider using a different structure for your data, which will keep all the data for each person together. With two people and only two attributes for each person, it doesn't really matter, but if you have many people and many attributes, it only takes one mistake in one of your lists to break sync. And if that happens, one or more people from your database will get the wrong data associated with them.

One possibility is to use a list of dicts, one dict for each person, for example

new_people = [
    {'age': 56, 'name': 'john'},
    {'age': 64, 'name': 'peter'}
]

      

And then you can easily print it out by doing something like this:

for d in new_people:
    print('My name is {0}, I am {1} years old.'.format(d['name'], d['age']))

      

Output:

My name is john, I am 56 years old.
My name is peter, I am 64 years old.

      


It is not that hard to convert existing people to dicts list. It's probably more readable to do it with a couple of loops for

, but I did it with this nested list / generator expression:

new_people = [dict(t) for t in (((k,v[i]) for k,v in People.items()) for i in range(len(People['name'])))]

PS. This is the Python convention for using lowercase names for regular variables. Names that start with an uppercase letter, such as People, are commonly used for activities. You don't have to follow this convention, but it makes it easier for people reading your code. You may notice that in the code you posted above, People are light blue because the SO code formatter reads its class name.

+1


source


This might be more intuitive for you:

strs = ["My name is " + People['name'][i] + ",i am " + str(People['age'][i]) + " old" for i in len(People)]
print(strs # ['My name is john,i am 56 old', 'My name is peter,i am 64 old'])

      

0


source







All Articles