2017-06-01 46 views
1

我真的在努力編寫代碼對於這個問題:迭代通過嵌套上市來獲取一個鍵值對

我的數據如下:

all_records = {u'ResourceRecordSets': [{u'Name': 'dev1.abc.com.', 
             u'ResourceRecords': [{u'Value': '10.0.3.214'}], 
             u'TTL': 300, 
             u'Type': 'A'}, 
             {u'Name': 'dev2.abc.com', 
             u'ResourceRecords': [{u'Value': '10.0.3.67'}], 
             u'TTL': 300, 
             u'Type': 'A'}]} 

我想通過這個名單來進行迭代當名稱是dev1.abc.com

我不想定義一個新的函數,我只是想在for循環中執行此操作。

+4

其實你應該** **要定義一個新的功能 - 但無論如何,你可以更新你的問題,以顯示你迄今爲止編寫的代碼? – quamrana

+1

此外,如果您對代碼進行格式化,則數據結構更加明顯,這將有所幫助。 –

回答

2

末點嘗試使用列表理解:

all_records = {u'ResourceRecordSets': [{u'Name': 'dev1.abc.com.', 
             u'ResourceRecords': [{u'Value': '10.0.3.214'}], 
             u'TTL': 300, 
             u'Type': 'A'}, 
             {u'Name': 'dev2.abc.com', 
             u'ResourceRecords': [{u'Value': '10.0.3.67'}], 
             u'TTL': 300, 
             u'Type': 'A'}]} 
value = [e['ResourceRecords'][0]['Value'] for e in all_records['ResourceRecordSets'] if e['Name']=="dev1.abc.com."] 
value 

value將是:

['10.0.3.214'] 
-1

如果你想使用高級功能:

  • 假設可能有多個"Value"字典裏面"ResourceRecords",並有可能有幾個"Name"出現。

    records = {u'ResourceRecordSets': [{u'ResourceRecords': [{u'Value': '10.0.3.214'}], u'Type': 'A', u'Name': 'dev1.abc.com.', u'TTL': 300}, {u'ResourceRecords': [{u'Value': '10.0.3.67'}], u'Type': 'A', u'Name': 'dev2.abc.com', u'TTL': 300}]} 
    
    name_to_find = "dev1.abc.com." 
    return_values = map(lambda sub_dict: [sub_list["Value"] for sub_list in sub_dict["ResourceRecords"]], 
            filter(lambda sub_dict: sub_dict["Name"] == name_to_find, 
              records["ResourceRecordSets"])) 
    
    print(list(return_dicts)) 
    
  • 如果僅存在一個"Value""ResourceRecords"內部字典和可能存在幾個"Name"發生。

    records = {u'ResourceRecordSets': [{u'ResourceRecords': [{u'Value': '10.0.3.214'}], u'Type': 'A', u'Name': 'dev1.abc.com.', u'TTL': 300}, {u'ResourceRecords': [{u'Value': '10.0.3.67'}], u'Type': 'A', u'Name': 'dev2.abc.com', u'TTL': 300}]} 
    
    name_to_find = "dev1.abc.com." 
    return_values = map(lambda sub_dict: sub_dict["ResourceRecords"][0]["Value"], 
            filter(lambda sub_dict: sub_dict["Name"] == name_to_find, 
              records["ResourceRecordSets"])) 
    
    print(list(return_dicts)) 
    
  • 如果只有一個"Name"發生,你最好使用一個for each環路與一休:

    records = {u'ResourceRecordSets': [{u'ResourceRecords': [{u'Value': '10.0.3.214'}], u'Type': 'A', u'Name': 'dev1.abc.com.', u'TTL': 300}, {u'ResourceRecords': [{u'Value': '10.0.3.67'}], u'Type': 'A', u'Name': 'dev2.abc.com', u'TTL': 300}]} 
    
    name_to_find = 'dev1.abc.com.' 
    return_values = [] 
    for sub_dict in records['ResourceRecordSets']: 
        if sub_dict['Name'] == name_to_find: 
         return_values = [record['Value'] for record in sub_dict['ResourceRecords']] 
         break 
    
+1

OP特別要求「價值」,而不是整個子字典。 –

+0

我忽略了它。我現在會更新答案。 – Strinnityk

2

這應該工作,也許你想以不同的值設置格式:

desired_name = 'dev1.abc.com' 
values = [] 
for resource in all_records['ResourceRecordSets']: 
    if resource['Name'] != desired_name: 
     continue 
    values = [record['Value'] for record in resource['ResourceRecords']] 
    break 

print(values) 

同樣的邏輯,但@ quamrana的建議:

desired_name = 'dev1.abc.com' 
values = [] 
for resource in all_records['ResourceRecordSets']: 
    if resource['Name'] == desired_name: 
     values = [record['Value'] for record in resource['ResourceRecords']] 
     break 

print(values) 
+1

Paco H,我認爲你應該反轉'desired_name'的測試來製作更簡單的代碼。 – quamrana

+0

@quamrana感謝您的評論,我添加了您的建議作爲另一種選擇。我個人比較喜歡我這樣做的方式,但歸結爲個人品味。 –

+1

Paco H,謝謝你包括我的建議。我個人的口味是代碼行數少,在這種情況下,將提取值的操作更接近關於選擇哪條記錄的決定。 – quamrana

0

我不知道這是否是一個錯字,但你確實有在dev1.abc.com.

all_records = {u'ResourceRecordSets': [{u'ResourceRecords': [{u'Value': '10.0.3.214'}], u'Type': 'A', u'Name': 'dev1.abc.com.', u'TTL': 300}, {u'ResourceRecords': [{u'Value': '10.0.3.67'}], u'Type': 'A', u'Name': 'dev2.abc.com', u'TTL': 300}]} 

name = 'dev1.abc.com.' 
for x in all_records['ResourceRecordSets']: 
    if x['Name'] == name: 
     value = x['ResourceRecords'][0]['Value'] 

print(value) 
# 10.0.3.214 
0

這簡單得多。不需要中斷聲明。

for i in range(len(all_records['ResourceRecordSets'])): if(all_records['ResourceRecordSets'][i]['Name']== 'dev1.abc.com.'): print all_records['ResourceRecordSets'][i]['ResourceRecords'][0]['Value']

+1

這僅適用於每個'i'的'all_records ['ResourceRecordSets'] [i] ['ResourceRecords']中只有一條記錄。 @ paco-h提供了適用於任何數量記錄的解決方案。 –

+0

我同意,但這是這個特定問題所需要的。對於'all_records ['ResourceRecordSets'] [i] ['ResourceRecords']中的n個值,包含另一個循環來說明所有可能的值是微不足道的。 – Pankaj

+0

由於數據顯然由DNS記錄組成(即「名稱」是FQDN,「值」包含IP地址),因此只有樣本不包含每個名稱的多個值纔是偶然事件。 DNS允許許多IP地址用於單個FQDN,所以我會考慮到這一點。 –

0
In [10]: new = list(filter(lambda x: x[u'Name'] == 'dev1.abc.com.', all_records[u'ResourceRecordSets']))[0]['ResourceRecords'] 

In [11]: new 
Out[11]: [{'Value': '10.0.3.214'}]