2012-05-11 64 views
0

我有一個名爲'score'的字典,其中的鍵是元組。 每個元組的形式是(x,y,tag)。Python天才們如何迭代Python元組中的單個值?

一些可能的得分初始化包括:

score[(0, 1, 'N')] = 1.0 
score[(0, 1, 'V')] = 1.5 
score[(0, 1, 'NP')] = 1.2 
score[(1, 2, 'N')] = 0.2 
score[(1, 2, 'PP')] = 0.1 
score[(1, 2, 'V')] = 0.1 

我想能夠保持x和y常數(例如,0,1),然後迭代對於標籤給定值(例如,N,V ,NP)。

任何Python geniuses都知道如何做到這一點?我正在尋找這方面的多個選項。謝謝。

+0

看起來像這個線程中的每個參賽者回答他們自己的問題版本。您能否更具體地瞭解您想要實現的目標,例如有問題的代碼應該返回或打印什麼? – georg

回答

7

什麼列表理解:

[ x[2] for x in score.keys() if x[0:2] == (0,1)] 
+0

我的+1。我更喜歡你的「if」部分。 '.keys()'可以被省略,因爲它會強制創建一個列表(不是一個大問題),並且字典通過鍵隱式地迭代。 – pepr

1

您必須遍歷所有元素,並檢查它們的鍵是否與您正在查找的內容匹配。

elems = (item for item in score.iteritems() if item[0][:2] == (0, 1)) 

你也可以使用一個迭代器,只給你的標籤值和元素,而不是整個項目的元組:

elems = ((item[0][2], item[1]) for item in score.iteritems() if item[0][:2] == (0, 1)) 

但是,您可以通過使用過濾迭代器很好地做到這一點如果你真的只需要變量值,而不是相應的元素,你可以做到這一點更容易:

tags = [k[2] for k in score if k[:2] == (0, 1)] 

演示:

>>> score 
{(0, 1, 'NP'): 1.2, 
(0, 1, 'V'): 1.5, 
(1, 2, 'N'): 0.2, 
(1, 2, 'PP'): 0.1, 
(1, 2, 'V'): 0.1} 

>>> list(item for item in score.iteritems() if item[0][:2] == (0, 1)) 
[((0, 1, 'NP'), 1.2), ((0, 1, 'V'), 1.5)] 

>>> list(((item[0][2], item[1]) for item in score.iteritems() if item[0][:2] == (0, 1))) 
[('NP', 1.2), ('V', 1.5)] 

>>> [k[2] for k in score if k[:2] == (0, 1)] 
['NP', 'V'] 
+0

絕對從你的迴應中學到了一些東西,ThiefMaster。這將派上用場。不過,看起來上面的回覆效率更高一些。感謝您花時間借我你的天才。 – Ussabin

+0

你應該用積極的態度來紀念這個時間。關於效率:沒有什麼區別。 – ThiefMaster

+0

是的...欣賞這個建議。但是,我的聲望仍然低於15(剛開始使用SOF),我還沒有投票。 – Ussabin

8
[tag for x,y,tag in score if x==0 and y==1] 
+2

我喜歡你的解決方案 - 它比kgiannakakis更乾淨。 – Tadeck

+0

@Tadeck我同意,除了kgiannakakis'明確使用'.keys()'對於那些沒有使用這個python習慣用法的人來說更加清晰,在這個習語中迭代通過一個字典遍歷這些鍵。說到這一點,我不使用'。keys()'要麼:D – jamylak

+0

幾乎我會做的,但我會讓它成爲一個生成器表達式。 '()'而不是'[]' –

1

我的智商是200,所以我希望這個計數:

score = {} 
score[(0, 1, 'N')] = 1.0 
score[(0, 1, 'V')] = 1.5 
score[(0, 1, 'NP')] = 1.2 
score[(1, 2, 'N')] = 0.2 
score[(1, 2, 'PP')] = 0.1 
score[(1, 2, 'V')] = 0.1 

from itertools import groupby 

def group_key(dict_key): 
    return dict_key[:2] 

sorted_keys = sorted(score) 
for group_key, group_of_dict_keys in groupby(sorted_keys, key=group_key): 
    print group_key 
    print [(dict_key, score[dict_key]) for dict_key in group_of_dict_keys] 

""" 
(0, 1) 
[((0, 1, 'N'), 1.0), ((0, 1, 'NP'), 1.2), ((0, 1, 'V'), 1.5)] 
(1, 2) 
[((1, 2, 'N'), 0.2), ((1, 2, 'PP'), 0.1), ((1, 2, 'V'), 0.1)] 
""" 
當然

如果你只是自己想要的標籤,然後改變回路:

for group_key, group_of_dict_keys in groupby(sorted_keys, key=group_key): 
    print group_key 
    tags = [tag for x, y, tag in group_of_dict_keys] 
    print tags 
""" 
(0, 1) 
['N', 'NP', 'V'] 
(1, 2) 
['N', 'PP', 'V'] 
""" 
+3

你的智商並不重要,你的答案的質量很重要。 'sorted_keys = sorted(score.keys())'可以(應該)替換爲'sorted_keys = sorted(得分)'。就你的答案的其他部分而言,他們沒問題。 – Tadeck

+1

謝謝,我現在編輯我的答案。我使用defaultdict fyi添加了另一個答案。 +1注意謝謝。 –

0

如果你只是想要標籤,那麼defaultdict將是最簡單的選擇。

score = {} 
score[(0, 1, 'N')] = 1.0 
score[(0, 1, 'V')] = 1.5 
score[(0, 1, 'NP')] = 1.2 
score[(1, 2, 'N')] = 0.2 
score[(1, 2, 'PP')] = 0.1 
score[(1, 2, 'V')] = 0.1 

from collections import defaultdict 

dict_ = defaultdict(list) 

for x,y,tag in score: 
    dict_[x,y].append(tag) 

#now get a result for any x,y we like: 
print dict_[0,1] 
"""['NP', 'N', 'V']"""