簡體   English   中英

Python 3:創建多個字典的列表具有相同的鍵但來自多個列表的不同值

[英]Python 3: Creating list of multiple dictionaries have same keys but different values coming from multiple lists

我正在使用 lxml 庫中的 xpath 解析 XML 的響應。 我得到結果並從中創建列表,如下所示:

object_name = [o.text for o in response.xpath('//*[name()="objectName"]')]
object_size_KB = [o.text for o in response.xpath('//*[name()="objectSize"]')]

我想使用列表為列表中的每個元素創建一個字典,然后將它們添加到最終列表中,如下所示:

[{'object_name': 'file1234', 'object_size_KB': 9347627},
{'object_name': 'file5671', 'objeobject_size_KBt_size': 9406875}]

我想要一個生成器,因為我將來可能需要從響應中搜索更多元數據,所以我希望我的代碼能夠面向未來並減少重復:

meta_names = {
'object_name': '//*[name()="objectName"]',
'object_size_KB': '//*[name()="objectSize"]'
             }
def parse_response(response, meta_names):
"""
input: response: api xml response text from lxml xpath
input: meta_names: key names used to generate dictionary per object
return: list of objects dictionary
"""
    mylist = []
   # create list of each xpath match assign them to variables
    for key, value in meta_names.items():
        mylist.append({key: [o.text for o in response.xpath(value)]})
    return mylist

然而 function 給了我這個:

[{'object_name': ['file1234', 'file5671']}, {'object_size_KB': ['9347627', '9406875']}]

我一直在論壇中尋找類似的案例,但找不到符合我需求的東西。 感謝你的幫助。

更新: Renneys 的答案是我想要的我剛剛調整了結果范圍的長度值,因為我並不總是每個 object 鍵的 xpath 的長度相同,而且每次我選擇第一個索引 [0] 時我的列表都有相同的長度。 現在 function 看起來像這樣。

def create_entries(root, keys):
    tmp = []
    for key in keys:
        tmp.append([o.text for o in root.xpath('//*[name()="' + key + '"]')])
    ret = []
    # print(len(tmp[0]))
    for i in range(len(tmp[0])):
        add = {}
        for j in range(len(keys)):
            add[keys[j]] = tmp[j][i]
        ret.append(add)
    return ret

我想這就是你要找的。

您可以使用 zip 將您的兩個列表組合成一個值對列表。
然后,您可以使用列表推導式或生成器表達式將值對與所需的鍵配對。

import pprint

object_name = ['file1234', 'file5671']
object_size = [9347627, 9406875]

[{'object_name': 'file1234', 'object_size_KB': 9347627},
{'object_name': 'file5671', 'objeobject_size_KBt_size': 9406875}]

[{'object_name': ['file1234', 'file5671']}, {'object_size_KB': ['9347627', '9406875']}]

# List Comprehension
obj_list = [{'object_name': name, 'object_size': size} for name,size in zip(object_name,object_size)]

pprint.pprint(obj_list)
print('\n')


# Generator Expression
generator = ({'object_name': name, 'object_size': size} for name,size in zip(object_name,object_size))

for obj in generator:
  print(obj)

實時代碼示例 -> https://onlinegdb.com/SyNSwd7jU


我認為接受的答案更有效,但這里有一個如何使用列表推導的示例。

meta_names = {
'object_name': ['file1234', 'file5671'],
'object_size_KB': ['9347627', '9406875'],
'object_text': ['Bob', 'Ross']
             }

def parse_response(meta_names):
  """
  input: response: api xml response text from lxml xpath
  input: meta_names: key names used to generate dictionary per object
  return: list of objects dictionary
  """
  # List comprehensions
  to_dict = lambda l: [{key:val for key,val in pairs} for pairs in l]

  objs = list(zip(*list([[key,val] for val in vals] for key,vals in meta_names.items())))

  pprint.pprint(to_dict(objs))  

parse_response(meta_names)

實時代碼-> https://onlinegdb.com/ryLq4PVjL

使用二維數組:

def createEntries(root, keys):
    tmp = []
    for key in keys:
        tmp.append([o.text for o in root.xpath('//*[name()="' + key + '"]')])
    ret = []
    for i in range(len(tmp)):
        add = {}
        for j in range(len(keys)):
            add[keys[j]] = tmp[j][i]
        ret.append(add)
    return ret

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM