【Python】對字典列表進行去重追加
阿新 • • 發佈:2019-01-26
update 分離 lan 無法 one _for tin format 之間 [TOC]
目標
現有字典列表
#
A = [ {dict1}, {dict2} ]
B = [ {dict3}, {dict2} ]
C = [ {dict3}, {dict4} ]
M = [A,B,C]
X = []
將M去重後的字典放入列表X中,得到X = [{dict1}, {dict2},{dict3}, {dict4}]
難點
字典列表
大家可能一開始會想到使用set()
函數轉化為集合,自動去重。但是集合是使用hash來計算並去重的,但是字典類型無法使用Hash計算。雖然可以使用類class
或者命名元組namedtupe
來替換字典,但是這次的場景是無法變更列表的產生源的。
列表無集合操作的方法
列表之間無法使用交並差(&
,|
,-
)的方式的集合計算方法
思路
# json,性能差 data = set([json.dumps(d) for d in data]) data = [json.loads(d) for d in data] # 這種方式只能對ABC生效,對M還需要再一次循環,瑪法 sortedlist = [] for item in listwhichneedssorting: if item not in sortedlist: sortedlist.append(item) # 這種縮短了兩行 for i in M: X.extend(filter(lamda s: s not in X, i)) # 使用extend()而不是append(),因為我們需要拼接的是字典列表,而不是列表的列表 # lamda s: s not in X, M 匿名函數,對i中的元素是否在X中進行判斷 # filter() 對上面匿名函數中不滿足條件(即重復的字典)進行過濾,返回尚未添加到X中的字典元素列表 # 使用extend()進行追加到X中
應用
主要是從neo4j中取出關系數據,分離節點,連接的關系,並轉換為前端適用的數據返回
def get_nodes_relationships(graph_list=None, ret_format=None): """ 將將關系與節點分離到各自的列表中 :param graph_list: :param ret_format: :return: """ node_list = [] relationship_list = [] for i in map(lambda x: x.get(‘graph‘, None).get(‘nodes‘), graph_list): node_list.extend(filter(lambda x: x not in node_list, i)) for m in map(lambda y: y.get(‘graph‘, None).get(‘relationships‘, None), graph_list): relationship_list.extend(filter(lambda x: x not in relationship_list, m)) # i和m都是由字典組成的列表,i為單字典列表,m為多字典列表, # 前端要求去重,這裏使用函數式語句返回沒有在結果列表中出現的字典,然後使用extend()追加 # 如果是面向d3,需要更改部分信息為d3適配 if ret_format == ‘d3‘: def to_d3(link): """ 面向d3框架更改關系的鍵名,增加節點的數字類型 :param link: 關系 :return: 更改後返回 """ # 使用推出鍵值對,重新推入的方式實現變更鍵名為前端可以識別的source link.update(source=link.pop(‘startNode‘)) # 使用推出鍵值對,重新推入的方式實現變更鍵名為前端可以識別的target link.update(target=link.pop(‘endNode‘)) value_map = { "meta_in": 1, "slave_of": 2, "shard_to": 3 } link[‘value‘] = value_map[link[‘type‘]] return link relationship_list = map(lambda x: to_d3(x), relationship_list) # 如果是面向echarts,需要更改部分信息為echarts適配 if ret_format == ‘echarts‘: def to_echarts(node=None, link=None): """ echarts適配 :param node: 單個節點 :param link: 單個關系 :return: 更改後的節點或者關系 """ if (node and link) or (node is None and link is None): print("fuck you") exit(1) if node: node[‘name‘] = node[‘id‘] node[‘draggable‘] = True node[‘category‘] = node[‘labels‘][0] del node[‘labels‘] # del node[‘properties‘] bom = node if link: # 使用推出鍵值對,重新推入的方式實現變更鍵名為前端可以識別的source link.update(source=link.pop(‘startNode‘)) # 使用推出鍵值對,重新推入的方式實現變更鍵名為前端可以識別的target link.update(target=link.pop(‘endNode‘)) link.update(category=link.pop(‘type‘)) del link[‘id‘] del link[‘properties‘] # del link[‘category‘] bom = link return bom node_list = map(lambda node: to_echarts(node), node_list) relationship_list = map(lambda relation: to_echarts(link=relation), relationship_list) # 為什麽要用set而不是list來轉化map對象: # 1.去重 # 2.減小對象大小,達到縮減內存占用 # 為什麽還是用list而不是set? # 1.dict對象不能被hash計算 ret = {"nodes": list(node_list), "links": list(relationship_list)} return ret
【Python】對字典列表進行去重追加