2014-09-21 115 views
3

我有一本字典:使用format_map与字典的Python

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

输出

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

'My name is john,i am 56 old' 

我想用format_map在一个循环中获得:

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

在字典等的每个项目:

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

但像一个循环:

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

给出:

KeyError: 'name' 

回答

2

str.format_map接受的映射。你不能传递额外的参数。

或者,您可以使用str.format,但嵌套{..}内部索引({0[name][{x}]})是不允许的。

>>> 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'] 
+0

@ PM2Ring,它适用于我(Python 2.7,Python 3.4)。看到这个:https://asciinema.org/a/12330 – falsetru 2014-09-21 10:23:19

+0

@ PM2Ring,如果字典中有两个以上的键,'map'版本会更有用。 (你不需要重复'人[']') – falsetru 2014-09-21 10:28:46

+0

@ PM2Ring,你是完全正确的。抱歉发现错误的想法。谢谢你指出。 – falsetru 2014-09-21 10:46:31

0

这可能是更直观的为您做到:

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']) 
+1

我会使用'len(people ['name'])'而不是像OP那样的硬编码2。顺便说一下,Python 3.x中的'print'是一个函数。 – falsetru 2014-09-21 08:05:53

+0

好点!谢谢@falsetru – alfasin 2014-09-21 15:20:52

1

你可以做两通格式:

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.' 
使用 str.formatzip/ map解决方法

...{{...}}...格式为...{...}...,所以适合致电format

1

您可能希望考虑为您的数据使用不同的结构,这样可以将每个人的所有数据放在一起。只有两个人,每个人只有两个属性,这并不重要,但是如果你有很多人和很多属性,它只会在你的一个列表中出现一个错误来破坏同步。如果发生这种情况,数据库中的一个或多个人将得到与他们相关的错误数据。

一种可能性是使用类型的字典列表,一个字典的每个人,如

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

然后你就可以轻松地做这样的打印:

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

输出:

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

将现有的人字典转换为字典列表并不难。这也可能是更具可读性与一对夫妇for循环做,但我这个嵌套列表理解/发电机表达式做到了:

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

PS。 Python中使用小写名称作为常规变量的约定。以大写字母开头的名称(如People)通常用于类。你不需要拥有来遵循这个约定,但它确实可以让正在阅读你的代码的人更容易。您可能会注意到,在您上面发布的代码中,People是淡蓝色,这是因为SO代码格式化程序认为它是类名。

+0

OP使用Python 3.x. Python 3.x中没有'dict.iteritems'。它应该是'项目'。 – falsetru 2014-09-21 10:25:36

+0

'len(People)'将始终返回2,即使列表中有更多人,因为给定字典中有两个键; 'len(People)'应该是'len(People ['name'])''。 – falsetru 2014-09-21 10:27:02

+1

我会这样做:'new_people = [{k:v [i] for k,v in People.items()} in in range(len(People ['name']))]''(using dict-comprehension) – falsetru 2014-09-21 10:33:29