如何在Python中按多个条件对项目进行排序?

huangapple go评论59阅读模式
英文:

How to sort items by multiple criteria in Python?

问题

correctlist = []
originallist = [{location:1, mgr:'Joe', region:'Frank'}, {location:2, mgr:'Sam', region:'Jess'}, {location:3, mgr:'Joe', region:'Frank'}, {location:4, mgr:'Sue', region:'Frank'}, {location:5, mgr:'Susan', region:'Jess'}]

# Should end up as [{location:1, mgr:'Joe', region:'Frank'}, {location:3, mgr:'Joe', region:'Frank'}, {location:4, mgr:'Sue', region:'Frank'}, {location:2, mgr:'Sam', region:'Jess'}, {location:5, mgr:'Susan', region:'Jess'}]

sortedlist = sorted(originallist, key=lambda k: (k['location']))

while sortedlist:
    for location in sortedlist:
        currregion = location['region']
        currmgr = location['mgr']
        for loc in sortedlist:
            if loc['region'] == currregion and loc['mgr'] == currmgr:
                correctlist.append(loc)
                sortedlist.remove(loc)
        for loc in sortedlist:
            if loc['region'] == currregion:
                currmgr = loc['mgr']
        for loc in sortedlist:
            if loc['mgr'] == currmgr and loc['region'] == currregion:
                correctlist.append(loc)
                sortedlist.remove(loc)
英文:

I have a list that's essentially [{location:1, mgr:'Joe', region:'Frank'}, {location:2, mgr:'Sam', region:'Jess'}, {location:3, mgr:'Joe', region:'Frank'}, {location:4, mgr:'Sue', region:'Frank'}, {location:5, mgr:'Susan', region:'Jess'}]. I need to get it into an order where the mgrs and regions are sorted by who has the lowest location number first but then grouped together. The mgrs and regions are names with no specific order except that their entries have to be together and the numbers correspond to specific locations, so they will never repeat,etc.

So the example should end up as:

"[{location:1, mgr:'Joe', region:'Frank'},{location:3, mgr:'Joe', region:'Frank'}, {location:4, mgr:'Sue', region:'Frank'}, {location:2, mgr:'Sam', region:'Jess'}, {location:5, mgr:'Susan', region:'Jess'}]"

Format doesn't really matter as I just need the locations in a correctly ordered list at the end. I haven't been able to find any similar examples and am struggling to figure out a way to approach this that isn't really convoluted (or even works).

I've tried a ton of different versions of this but my general thought was to iterate through and move entries to another list in the correct order. I've gotten close but there have still been entries not in the correct order. I also tried to sort with additional keys but kept running into issues with it sorting alphabetically or solely by the locations.

    correctlist = []
    originallist = [{location:1,mgr:'Joe',region:'Frank'},{location:2,mgr:'Sam',region:'Jess'},{location:3,mgr:'Joe',region:'Frank'},{location:4, mgr:'Sue', region:'Frank'},{location:5, mgr:'Susan', region:'Jess'}]

#Should end up as [{location:1,mgr:'Joe',region:'Frank'},{location:3,mgr:'Joe',region:'Frank'},{location:4, mgr:'Sue', region:'Frank'},{location:2,mgr:'Sam',region:'Jess'},{location:5, mgr:'Susan', region:'Jess'}]

    sortedlist = sorted(originallist, key=lambda k: (k['location']))

    while sortedlist:
        for location in sortedlist:
            currregion = location['region']
            currmgr = location['mgr']
            for locationin sortedlist:
                if location['region'] == currregion and location['mgr'] == currmgr:
                    correctlist.append(number)
                    sortedlist.remove(number)
            for location in sortedlist:
                if location['region'] == curregion:
                    currmgr = location['mgr']
            for locationin sortedlist:
                if location['mgr'] == currmgr and location['region'] == curregion:
                    correctlist.append(location)
                    sortedlist.remove(location)

答案1

得分: 0

以下是您要的代码翻译:

# 最佳和简单的方法来在Python中将元素分组在一起通常是使用一个字典的列表。

# 当我们将所有东西都很好地分组在区域的子列表和经理的子子列表中时,我们可以对每个子子列表进行排序,然后对每个子列表进行排序。

# 如果每个经理的子子列表都按位置排序,那么最低位置将在其第一个元素中,因此我们可以通过查看每个经理的子子列表的第一个元素的位置来对经理的子子列表进行排序。

# 然后,我们可以将经理的子子列表链接在一起,表示区域的排序子列表。

# 然后,每个区域子列表都进行排序,因此其最低位置将在其第一个元素中,因此我们可以通过查看每个区域子列表的第一个元素的位置来对区域子列表的列表进行排序。

# 然后,我们可以将所有子列表链接在一起,形成一个排序后的列表。

from itertools import chain

originallist = [{'location': 1, 'mgr': 'Joe', 'region': 'France'},
               {'location': 2, 'mgr': 'Sam', 'region': 'Japan'},
               {'location': 3, 'mgr': 'Joe', 'region': 'France'},
               {'location': 4, 'mgr': 'Sue', 'region': 'France'},
               {'location': 5, 'mgr': 'Susan', 'region': 'Japan'}]

# 我将'Franck'替换为'France','Jessica'替换为'Japan',以避免区域和经理之间的混淆。

def grouped_by_region(originallist):
    regions = {}
    for lmr in originallist:
        regions.setdefault(lmr['region'], []).append(lmr)
    return regions

def grouped_by_mgr(region):
    by_mgr = {}
    for lmr in region:
        by_mgr.setdefault(lmr['mgr'], []).append(lmr)
    return by_mgr

def sorted_by_region_mgr_location(originallist):
    regions = grouped_by_region(originallist)
    for region_name, region in regions.items():
        by_mgr = grouped_by_mgr(region)
        for group in by_mgr.values():
            group.sort(key=lambda lmr: lmr['location'])  # 在每个经理组内排序
        sorted_groups = sorted(by_mgr.values(), key=lambda group: group[0]['location'])  # 在每个区域内排序经理
        regions[region_name] = list(chain.from_iterable(sorted_groups))
    return list(chain.from_iterable(sorted(regions.values(), key=lambda region: region[0]['location']))

print(sorted_by_region_mgr_location(originallist))

结果:

[{'location': 1, 'mgr': 'Joe', 'region': 'France'},
 {'location': 3, 'mgr': 'Joe', 'region': 'France'},
 {'location': 4, 'mgr': 'Sue', 'region': 'France'},
 {'location': 2, 'mgr': 'Sam', 'region': 'Japan'},
 {'location': 5, 'mgr': 'Susan', 'region': 'Japan'}]
英文:

The best and simple way to group elements together in python is usually to use a dict of lists.

When we have grouped everything nicely in sublists of regions and subsublists of managers, we can sort each subsublist and then each sublist.

If each manager's subsublist is sorted by location, then the lowest location is going to be in its first element, so we can sort the sublist of manager's subsublists by looking at the location of the first element of each manager's subsublist.

Then we can chain the manager's subsublists together into a sorted sublist representing the region.

Then each region sublist is sorted, so its lowest location is going to be in its first element, so we can sort the list of region sublists by looking at the location of the first element of each region sublist.

Then we can chain all the sublists together into a sorted list.

from itertools import chain

originallist = [{'location':1,'mgr':'Joe','region':'France'},{'location':2,'mgr':'Sam','region':'Japan'},{'location':3,'mgr':'Joe','region':'France'},{'location':4, 'mgr':'Sue', 'region':'France'},{'location':5, 'mgr':'Susan', 'region':'Japan'}]
# I replaced 'Franck' with 'France' and 'Jessica' with 'Japan' to avoid confusiong between regions and managers

def grouped_by_region(originallist):
    regions = {}
    for lmr in originallist:
        regions.setdefault(lmr['region'], []).append(lmr)
    return regions

# print(grouped_by_region(originallist))
## {'France': [{'location': 1, 'mgr': 'Joe', 'region': 'France'}, {'location': 3, 'mgr': 'Joe', 'region': 'France'}, {'location': 4, 'mgr': 'Sue', 'region': 'France'}],
##  'Japan': [{'location': 2, 'mgr': 'Sam', 'region': 'Japan'}, {'location': 5, 'mgr': 'Susan', 'region': 'Japan'}]}

def grouped_by_mgr(region):
    by_mgr = {}
    for lmr in region:
        by_mgr.setdefault(lmr['mgr'], []).append(lmr)
    return by_mgr

# regions = grouped_by_region(originallist)
# print(grouped_by_mgr(regions['France']))
## {'Joe': [{'location': 1, 'mgr': 'Joe', 'region': 'France'}, {'location': 3, 'mgr': 'Joe', 'region': 'France'}], 'Sue': [{'location': 4, 'mgr': 'Sue', 'region': 'France'}]}

## PUTTING IT ALL TOGETHER
def sorted_by_region_mgr_location(originallist):
    regions = grouped_by_region(originallist)
    for region_name, region in regions.items():
        #print('\nregion: ', region_name)
        by_mgr = grouped_by_mgr(region)
        #print('grouped by mgr: ', by_mgr)
        for group in by_mgr.values():
            group.sort(key=lambda lmr: lmr['location'])  # sort within each manager group
        sorted_groups = sorted(by_mgr.values(), key=lambda group: group[0]['location'])  # sort managers within each region
        #print('sorted groups: ', sorted_groups)
        regions[region_name] = list(chain.from_iterable(sorted_groups))
        #print('final list: ', regions[region_name])
    #print('\n\nregions before chaining: ', regions)
    return list(chain.from_iterable(sorted(regions.values(), key=lambda region: region[0]['location'])))

print(
    sorted_by_region_mgr_location(originallist)
)

Result:

[{'location': 1, 'mgr': 'Joe', 'region': 'France'}, {'location': 3, 'mgr': 'Joe', 'region': 'France'}, {'location': 4, 'mgr': 'Sue', 'region': 'France'}, {'location': 2, 'mgr': 'Sam', 'region': 'Japan'}, {'location': 5, 'mgr': 'Susan', 'region': 'Japan'}]

huangapple
  • 本文由 发表于 2023年2月10日 07:49:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75405631.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定