簡體   English   中英

對某些位置的某些列表元素進行排序,其他位置保持不變

[英]Sort some list elements in certain positions, leaving other positions unchanged

我有一個元素列表,以及相關的排序鍵

data = [
 {'data': 0},
 {'key': 'foo', 'data': 1},
 {'key': 'bar', 'data': 2},
 {'data': 3},
 {'key': 'foo', 'data': 4},
 {'key': 'bar', 'data': 5},
 {'key': 'bar', 'data': 6},
 {'data': 7}
]

有些元素有排序key ,有些沒有。 我有一個對一些鍵進行排序的外部表:

ORDER = ['bar', 'foo', 'baz']

預期結果:

[
 {'data': 0},
 {'key': 'bar', 'data': 2},
 {'key': 'bar', 'data': 5},
 {'data': 3},
 {'key': 'bar', 'data': 6},
 {'key': 'foo', 'data': 1},
 {'key': 'foo', 'data': 4},
 {'data': 7}
]

我需要對數組進行排序,只移動帶有鍵的元素,不移動具有相同鍵的元素。 (基本上,如果鍵比較不需要,我對具有不交換元素的元素有部分順序)。 據我所知,現有的list.sort / sorted (在 Python 中)不支持這種類型的排序。

我強烈懷疑這個問題已經解決了很多次,但我找不到合適的名稱來搜索。

這種類型的排序如何被調用?

創建排序記錄的迭代器:

it1 = iter(sorted((d for d in data if 'key' in d), 
                  key=lambda d_: ORDER.index(d_['key'])))

接下來,編寫一個列表推導式以選擇性地用“key”覆蓋記錄,而其他記錄保持不變。

res = [d if 'key' not in d else next(it1) for d in data]
print (res)
# [{'data': 0},
#  {'key': 'bar', 'data': 2},
#  {'key': 'bar', 'data': 5},
#  {'data': 3},
#  {'key': 'bar', 'data': 6},
#  {'key': 'foo', 'data': 1},
#  {'key': 'foo', 'data': 4},
#  {'data': 7}]

幾點:

  • 可能值得將ORDER轉換為將鍵映射到位置的字典,因此查找是恆定的時間。 這應該會降低排序步驟的復雜性。

  • sorted返回一個列表,然后將其轉換為迭代器,因此無法避免中間列表。

如果您的鍵很少,您可以在 O(n) 時間內執行此操作,例如使用桶排序之類的東西:

import pprint
from collections import defaultdict
from itertools import chain

# create buckets
buckets, no_key = defaultdict(list), {}
for i, d in enumerate(data):
    if 'key' in d:
        buckets[d['key']].append(d)
    else:
        no_key[i] = d

# create one sorted list for elements with keys, basically iterate over the buckets in ORDER
chained = list(chain.from_iterable([buckets[key] for key in ORDER]))[::-1]

# combine the two iterables, chained and no_key into the final result
final = [no_key.pop(i) if i in no_key else chained.pop() for i in range(len(data))]
pprint.pprint(final)

Output

[{'data': 0},
 {'data': 2, 'key': 'bar'},
 {'data': 5, 'key': 'bar'},
 {'data': 3},
 {'data': 6, 'key': 'bar'},
 {'data': 1, 'key': 'foo'},
 {'data': 4, 'key': 'foo'},
 {'data': 7}]

暫無
暫無

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

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