2015-06-23 35 views
1

我有以下Python字典:排序并重新编号值

road_dict = {0:[1L,2L], 1:[3L], 2:[4L,5L]} 
dist_dict = {1L: 4.1, 2L: 2.1, 3L: 4, 4L: 2.1, 5L: 6} 
num_dict = {0:[2,4], 1:[5], 2:[1,3] 

第一个,road_dict,有道路标识作为键和值相关联的归属标识。第二个是dist_dict,它具有与沿着道路的键和它们的距离相同的家庭ID作为值。第三个,num_dict,与作为值的相同家庭相关的键和数字具有相同的道路ID。

我试图根据它们在道路上的距离重新编号这些房屋。 的什么,我希望得到一个简单的版本是这样

new_dict = {0:[4,2], 1:[5], 2:[1,3]} 

对于键0,数字的顺序已切换,因为家庭ID 1L更远沿着比2L的道路。这也意味着4现在属于1L,而2属于2L。

但是,由于我的字典是分开的,我还有一些其他问题。我正在寻找一种将信息汇总在一本字典中的方法,以便我可以更轻松地跟踪哪个家庭号码属于哪个家庭ID。

最终,我在寻找什么,以实现本 - 1场我试图更新(用新的,分类号)的索引:

final_dict = {1L:{1:4}, 2L:{1:2}, 3L:{1:5}, 4L:{1:1}, 5L:{1:3}} 

一我刚刚意识到的缺失部分可能很有用这创建了一个字典,其中每个房屋沿线的顺序都有一个简单的增量。我认为这属于我原来的问题。 :

another_dict = {0:[2,1], 1:[1], 2:[1,2]} 

UPDATE我尝试下面的代码使用下面的字典,但事情仍然没有正确排序。虽然家庭是按距离排序,并准备好按顺序编号,但我也希望保留现有的一组数字,并根据距离将它们切换到正确的顺序。该代码允许每个家庭保持其现有号码,而不管距离顺序如何。

i_road_dict = {421: [32L, 33L, 34L], 422: [9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 27L, 28L, 29L, 35L, 36L, 37L, 38L, 39L], 423: [66L, 67L, 72L, 73L, 76L], 623: [2L], 624: [0L], 627: [3L, 4L], 629: [86L], 317: [50L, 63L, 64L, 65L, 70L, 71L, 74L, 75L, 81L, 82L, 83L, 85L, 87L, 88L]} 

i_num_dict = {421: [15, 19, 21], 422: [31, 33, 35, 39, 43, 31, 29, 25, 23, 19, 15, 41, 49, 47, 9, 7, 11, 13, 17], 423: [11, 13, 17, 23, 27], 623: [1], 624: [13], 627: [9, 5], 629: [7], 317: [109, 151, 45, 47, 143, 141, 133, 131, 101, 95, 91, 81, 57, 63]} 

i_distance_dict = {0L: 61.488059367717, 2L: 8.021516228782936, 3L: 45.52003866488311, 4L: 25.20730241437668, 9L: 157.844303290623, 10L: 162.61477713824982, 11L: 177.70675687888885, 12L: 194.7672626115625, 13L: 205.85748324109224, 14L: 151.29798366856477, 15L: 147.66380499017282, 16L: 119.9462825595851, 17L: 114.98507682692828, 18L: 98.45714293590342, 19L: 87.46475300724273, 27L: 209.53486929892026, 28L: 232.3460547737345, 29L: 239.89698687340757, 32L: 71.13973224724995, 33L: 90.16514887960331, 34L: 106.48078486409304, 35L: 30.04092989941455, 36L: 39.961250890703326, 37L: 53.44419657185303, 38L: 83.59339524297145, 39L: 85.66697660333085, 50L: 549.0312971771257, 63L: 753.3816549180551, 64L: 225.80699058127138, 65L: 237.74936014259308, 66L: 58.12282403458027, 67L: 63.3770825337218, 70L: 708.6717387628081, 71L: 704.5817839747034, 72L: 87.27533124959758, 73L: 113.56828281454557, 74L: 658.1701619456403, 75L: 654.8787862943727, 76L: 137.46561448886376, 81L: 501.846856735727, 82L: 478.70973384256945, 83L: 456.2651041053348, 85L: 407.21753873616143, 86L: 34.367967658321774, 87L: 286.4419958357572, 88L: 317.3584642656698} 

使用此代码后:

i_homes = [] 
for road_id, home_ids in i_road_dict.items(): 
    i_home_numbers_on_road = i_num_dict[road_id] 
    for home_id, home_number in zip(home_ids, i_home_numbers_on_road): 
     home = {} 
     home['home_id'] = home_id 
     home['home_number'] = home_number 
     home['road_id'] = road_id 
     home['distance'] = distance_dict[home_id] 
     i_homes.append(home) 

i_sorted_dict = {} 
for road_id in i_road_dict: 
    i_homes_on_road = [home for home in i_homes if home['road_id'] == road_id] 
    i_ordered_homes = sorted(i_homes_on_road, key=lambda h: h['distance']) 
    i_sorted_dict[road_id] = i_ordered_homes 

我得到了这样的结果:

i_sorted_dict = {421: [{'home_id': 32L, 'home_number': 15, 'road_id': 421, 'distance': 71.13973224724995}, {'home_id': 33L, 'home_number': 19, 'road_id': 421, 'distance': 90.16514887960331}, {'home_id': 34L, 'home_number': 21, 'road_id': 421, 'distance': 106.48078486409304}], 422: [{'home_id': 35L, 'home_number': 9, 'road_id': 422, 'distance': 30.04092989941455}, {'home_id': 36L, 'home_number': 7, 'road_id': 422, 'distance': 39.961250890703326}, {'home_id': 37L, 'home_number': 11, 'road_id': 422, 'distance': 53.44419657185303}, {'home_id': 38L, 'home_number': 13, 'road_id': 422, 'distance': 83.59339524297145}, {'home_id': 39L, 'home_number': 17, 'road_id': 422, 'distance': 85.66697660333085}, {'home_id': 19L, 'home_number': 15, 'road_id': 422, 'distance': 87.46475300724273}, {'home_id': 18L, 'home_number': 19, 'road_id': 422, 'distance': 98.45714293590342}, {'home_id': 17L, 'home_number': 23, 'road_id': 422, 'distance': 114.98507682692828}, {'home_id': 16L, 'home_number': 25, 'road_id': 422, 'distance': 119.9462825595851}, {'home_id': 15L, 'home_number': 29, 'road_id': 422, 'distance': 147.66380499017282}, {'home_id': 14L, 'home_number': 31, 'road_id': 422, 'distance': 151.29798366856477}, {'home_id': 9L, 'home_number': 31, 'road_id': 422, 'distance': 157.844303290623}, {'home_id': 10L, 'home_number': 33, 'road_id': 422, 'distance': 162.61477713824982}, {'home_id': 11L, 'home_number': 35, 'road_id': 422, 'distance': 177.70675687888885}, {'home_id': 12L, 'home_number': 39, 'road_id': 422, 'distance': 194.7672626115625}, {'home_id': 13L, 'home_number': 43, 'road_id': 422, 'distance': 205.85748324109224}, {'home_id': 27L, 'home_number': 41, 'road_id': 422, 'distance': 209.53486929892026}, {'home_id': 28L, 'home_number': 49, 'road_id': 422, 'distance': 232.3460547737345}, {'home_id': 29L, 'home_number': 47, 'road_id': 422, 'distance': 239.89698687340757}], 423: [{'home_id': 66L, 'home_number': 11, 'road_id': 423, 'distance': 58.12282403458027}, {'home_id': 67L, 'home_number': 13, 'road_id': 423, 'distance': 63.3770825337218}, {'home_id': 72L, 'home_number': 17, 'road_id': 423, 'distance': 87.27533124959758}, {'home_id': 73L, 'home_number': 23, 'road_id': 423, 'distance': 113.56828281454557}, {'home_id': 76L, 'home_number': 27, 'road_id': 423, 'distance': 137.46561448886376}], 623: [{'home_id': 2L, 'home_number': 1, 'road_id': 623, 'distance': 8.021516228782936}], 624: [{'home_id': 0L, 'home_number': 13, 'road_id': 624, 'distance': 61.488059367717}], 627: [{'home_id': 4L, 'home_number': 5, 'road_id': 627, 'distance': 25.20730241437668}, {'home_id': 3L, 'home_number': 9, 'road_id': 627, 'distance': 45.52003866488311}], 629: [{'home_id': 86L, 'home_number': 7, 'road_id': 629, 'distance': 34.367967658321774}], 317: [{'home_id': 64L, 'home_number': 45, 'road_id': 317, 'distance': 225.80699058127138}, {'home_id': 65L, 'home_number': 47, 'road_id': 317, 'distance': 237.74936014259308}, {'home_id': 87L, 'home_number': 57, 'road_id': 317, 'distance': 286.4419958357572}, {'home_id': 88L, 'home_number': 63, 'road_id': 317, 'distance': 317.3584642656698}, {'home_id': 85L, 'home_number': 81, 'road_id': 317, 'distance': 407.21753873616143}, {'home_id': 83L, 'home_number': 91, 'road_id': 317, 'distance': 456.2651041053348}, {'home_id': 82L, 'home_number': 95, 'road_id': 317, 'distance': 478.70973384256945}, {'home_id': 81L, 'home_number': 101, 'road_id': 317, 'distance': 501.846856735727}, {'home_id': 50L, 'home_number': 109, 'road_id': 317, 'distance': 549.0312971771257}, {'home_id': 75L, 'home_number': 131, 'road_id': 317, 'distance': 654.8787862943727}, {'home_id': 74L, 'home_number': 133, 'road_id': 317, 'distance': 658.1701619456403}, {'home_id': 71L, 'home_number': 141, 'road_id': 317, 'distance': 704.5817839747034}, {'home_id': 70L, 'home_number': 143, 'road_id': 317, 'distance': 708.6717387628081}, {'home_id': 63L, 'home_number': 151, 'road_id': 317, 'distance': 753.3816549180551}]} 

至少对于道路422家仍然无序。我期待这个(用手工完成的,所以我希望我没有错过任何东西),它调换了现有的数字基于距离对它们进行排序:

422: [{'home_id': 35L, 'home_number': 7, 'road_id': 422, 'distance': 30.04092989941455}, {'home_id': 36L, 'home_number': 9, 'road_id': 422, 'distance': 39.961250890703326}, {'home_id': 37L, 'home_number': 11, 'road_id': 422, 'distance': 53.44419657185303}, {'home_id': 38L, 'home_number': 13, 'road_id': 422, 'distance': 83.59339524297145}, {'home_id': 39L, 'home_number': 15, 'road_id': 422, 'distance': 85.66697660333085}, {'home_id': 19L, 'home_number': 17, 'road_id': 422, 'distance': 87.46475300724273}, {'home_id': 18L, 'home_number': 19, 'road_id': 422, 'distance': 98.45714293590342}, {'home_id': 17L, 'home_number': 23, 'road_id': 422, 'distance': 114.98507682692828}, {'home_id': 16L, 'home_number': 25, 'road_id': 422, 'distance': 119.9462825595851}, {'home_id': 15L, 'home_number': 29, 'road_id': 422, 'distance': 147.66380499017282}, {'home_id': 14L, 'home_number': 31, 'road_id': 422, 'distance': 151.29798366856477}, {'home_id': 9L, 'home_number': 31, 'road_id': 422, 'distance': 157.844303290623}, {'home_id': 10L, 'home_number': 33, 'road_id': 422, 'distance': 162.61477713824982}, {'home_id': 11L, 'home_number': 35, 'road_id': 422, 'distance': 177.70675687888885}, {'home_id': 12L, 'home_number': 39, 'road_id': 422, 'distance': 194.7672626115625}, {'home_id': 13L, 'home_number': 41, 'road_id': 422, 'distance': 205.85748324109224}, {'home_id': 27L, 'home_number': 43, 'road_id': 422, 'distance': 209.53486929892026}, {'home_id': 28L, 'home_number': 47, 'road_id': 422, 'distance': 232.3460547737345}, {'home_id': 29L, 'home_number': 49, 'road_id': 422, 'distance': 239.89698687340757}] 

另一个更新的问题是与创建作为答案提供的final_dict。我适应了那种新的号码,并与有序的家庭,而不是 “homes_on_road” 拉链:

i_final_dict = {} 
for road_id in i_road_dict: 
    i_homes_on_road = [home for home in i_homes if home['road_id'] == road_id] 
    i_ordered_homes = sorted(i_homes_on_road, key=lambda h: h['distance']) 
    #i_ordered_nums = [home['home_number'] for home in i_ordered_homes] 
    i_ordered_nums = sorted([home['home_number'] for home in i_ordered_homes]) 
    for home, new_number in zip(i_ordered_homes, i_ordered_nums): 
     i_final_dict[home['home_id']] = {sort_num_idx:new_number} 
+0

记住了''dict''本质上是无序的。你可能想使用[''dict.items()'']将它转换为包含键/值对的元组列表(https://docs.python.org/2/library/stdtypes.html#dict .items),然后对其进行排序。 – pzp

+0

所以......你不想把房屋重新编号为1,2,3 ......你想在街道上保留这组数据,并按照距离顺序重新应用到街道上的房屋? – TessellatingHeckler

+0

@TessellatingHeckler我想做两个。我试着在一些更多的数据上测试你的代码,它不起作用。我想知道我是否正在适应某些不正确的东西。 – user25976

回答

1

它是否必须是简洁的?如何使每家一本字典,所有的相关信息,并把这些在列表中:

from pprint import pprint 

road_dict = {0:[1L,2L], 1:[3L], 2:[4L,5L]} # road_id:home_id 
dist_dict = {1L: 4.1, 2L: 2.1, 3L: 4, 4L: 2.1, 5L: 6} # home_id:distance 
num_dict = {0:[2,4], 1:[5], 2:[1,3]} # road_id:[house_numbers] 

homes = [] 
for road_id, home_ids in road_dict.items(): 
    home_numbers_on_road = num_dict[road_id] 

    for home_id, home_number in zip(home_ids, home_numbers_on_road): 
     home = {'home_id':  home_id, 
       'home_number': home_number, 
       'road_id':  road_id, 
       'distance': dist_dict[home_id]} 

     homes.append(home) 

pprint(homes) 

给出一个列表,字典每个家庭,所有的事情保持在一起:

[{'distance': 4.1, 'home_id': 1L, 'home_number': 2, 'road_id': 0}, 
{'distance': 2.1, 'home_id': 2L, 'home_number': 4, 'road_id': 0}, 
{'distance': 4, 'home_id': 3L, 'home_number': 5, 'road_id': 1}, 
{'distance': 2.1, 'home_id': 4L, 'home_number': 1, 'road_id': 2}, 
{'distance': 6, 'home_id': 5L, 'home_number': 3, 'road_id': 2}] 

然后你得到的东西建立一个更容易的时间出来的:

new_dict = {} 
for road_id in road_dict: 
    homes_on_road = [home for home in homes if home['road_id'] == road_id] 
    ordered_homes = sorted(homes_on_road, key=lambda h: h['distance']) 
    new_dict[road_id] = ordered_homes 


pprint(new_dict) 

给出:

{0: [{'distance': 2.1, 'home_id': 2L, 'home_number': 4, 'road_id': 0}, 
    {'distance': 4.1, 'home_id': 1L, 'home_number': 2, 'road_id': 0}], 
1: [{'distance': 4, 'home_id': 3L, 'home_number': 5, 'road_id': 1}], 
2: [{'distance': 2.1, 'home_id': 4L, 'home_number': 1, 'road_id': 2}, 
    {'distance': 6, 'home_id': 5L, 'home_number': 3, 'road_id': 2}]} 

这是你的0:4,2, 1:5, 2:1,3的中间结果。

虽然这有重新排序的家园而不是重新编号为。但是,这是什么意思,重新编号在街道2上的家5,当它是街道2上唯一的家?假设他们走1,2,...,每个街道:

new_dict = {} 
for road_id in road_dict: 
    homes_on_road = [home for home in homes if home['road_id'] == road_id] 
    ordered_homes = sorted(homes_on_road, key=lambda h: h['distance']) 
    for position, home in enumerate(ordered_homes): 
     home['home_number'] = position + 1 

    new_dict[road_id] = ordered_homes 

pprint(new_dict) 

其中给出:

{0: [{'distance': 2.1, 'home_id': 2L, 'home_number': 1, 'road_id': 0}, 
    {'distance': 4.1, 'home_id': 1L, 'home_number': 2, 'road_id': 0}], 
1: [{'distance': 4, 'home_id': 3L, 'home_number': 1, 'road_id': 1}], 
2: [{'distance': 2.1, 'home_id': 4L, 'home_number': 1, 'road_id': 2}, 
    {'distance': 6, 'home_id': 5L, 'home_number': 2, 'road_id': 2}]} 

这已经把房子在他们身体中(按距离)的顺序显示出来,依次从最近到最远依次重新编号。

[编辑:也许修正]

编辑:难道这就是final_dict应该是什么?

# order the homes by distance 
# pair up the homes by position with the home_numbers by distance 

final_dict = {} 
for road_id in road_dict: 
    homes_on_road = [home for home in homes if home['road_id'] == road_id] 
    ordered_homes = sorted(homes_on_road, key=lambda h: h['distance']) 
    ordered_nums = [home['home_number'] for home in ordered_homes] 

    for home, new_number in zip(homes_on_road, ordered_nums): 
     final_dict[home['home_id']] = {1:new_number} 

pprint(final_dict) 

,并提供:

{1L: {1: 4}, 2L: {1: 2}, 3L: {1: 5}, 4L: {1: 1}, 5L: {1: 3}} 
+0

你能解释你所做的更正吗?此外,有关如何将其转换为我期望的最终格式的想法? – user25976

+0

纠正是我在和自己辩论是否最后一个应该按home_id重新排列道路列表,或重新编号home_number,还是两者。我开始时认为重新排列名单是错误的,因为房屋不能移动。我意识到房子没有移动,他们被列在错误的顺序,并通过重新排列名单,这些名单被排序为房屋订单(按距离)。我不明白你想要的最终格式,或者another_dict与什么有关。 – TessellatingHeckler

+0

@ user25976我添加了更多。 – TessellatingHeckler

1

制作new_dict

>>> new_dict = dict() 
>>> for ikey in road_dict: 
     l = list(sorted(num_dict[ikey],key = lambda x:dist_dict[road_dict[ikey][num_dict[ikey].index(x)]])) 
     print l 
>>> for ikey in road_dict: 
     l = list(sorted(num_dict[ikey],key = lambda x:dist_dict[road_dict[ikey][num_dict[ikey].index(x)]])) 
     new_dict[ikey] = l 


>>> new_dict 
{0: [4, 2], 1: [5], 2: [1, 3]} 

制作final_dict

>>> x = 'x' 
>>> for ikey in road_dict: 
     for j in range(len(road_dict[ikey])): 
      final_dict[road_dict[ikey][j]] = {x : new_dict[ikey][j]} 


>>> final_dict 
{1L: {'x': 4}, 2L: {'x': 2}, 3L: {'x': 5}, 4L: {'x': 1}, 5L: {'x': 3}} 

希望这对你有用!

+0

关于pzp的评论,我会有任何问题吗?此外,我添加了一个小编辑,其中可能包含或可能不属于此线程。 – user25976