2014-09-21 114 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