在Python字典中对值进行排序和重新编号

时间:2015-06-23 21:14:25

标签: python dictionary

我有以下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,道路ID作为键,家庭ID作为值关联。第二个,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是我尝试更新的字段的索引(使用新的已排序的数字):< / p>

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]}

更新我使用以下词典尝试了以下代码,但事情仍未正确排序。虽然房屋按距离排序并准备按顺序编号,但我也希望保留现有数字的集合,并根据距离将它们切换到正确的顺序。此代码允许每个家庭保留现有的号码而不管距离顺序。

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的创建。我改编了新的数字,并用订购的房屋压缩而不是&#34; homes_on_road&#34;:

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}

2 个答案:

答案 0 :(得分: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}}

我希望这适合你!

答案 1 :(得分: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上唯一的家时,在街道2上重新装修5号房屋是什么意思呢?假设他们在每条街上都是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}}