按顺序有效地对列表进行排序

Rag*_*fin 4 python python-3.x

可以说我有两个列表:

sequence = [25, 15, 20, 15, 25, 25]
l = [(25, 'banana'), 
     (25, 'apple'), 
     (25, 'pine'), 
     (20, 'soap'), 
     (15, 'rug'), 
     (15, 'cloud')]
Run Code Online (Sandbox Code Playgroud)

我想按顺序排序第二个列表l.在示例中,数字25出现多次,在这种情况下,只要它具有值25,哪个元组在该位置并不重要.列表将始终具有相同的长度.

我目前的做法是:

r = list(range(len(sequence)))

for i, v in enumerate(sequence):
    for e in l:
        if e[0] == v:
            r[i] = e
            l.remove(e)
print(r)
Run Code Online (Sandbox Code Playgroud)

可能的输出:

[(25,'banana'),(15,'rug'),(20,'soap'),(15,'cloud')(25,'apple'),(25,'pine')]

你看到更好的方法吗?

谢谢你的帮助!

笨人

Jea*_*bre 5

是.首先创建一个默认的dictonary,数字作为键,并命名为每个键的值(作为列表)

sequence = [25, 15, 20, 15, 25, 25]
l = [(25, 'banana'),
     (25, 'apple'),
     (25, 'pine'),
     (20, 'soap'),
     (15, 'rug'),
     (15, 'cloud')]

from collections import defaultdict

d = defaultdict(list)
for i,n in l:
    d[i].append(n)
Run Code Online (Sandbox Code Playgroud)

然后,迭代序列并从相关列表中删除(匹配号码)list.pop,一次删除一个项目(每个列表中必须有足够的项目,并且键必须在那里,否则你将得到一个python异常(空列表)/key error)):

result = [(i,d[i].pop()) for i in sequence]
print(result)
Run Code Online (Sandbox Code Playgroud)

结果:

[(25, 'pine'), (15, 'cloud'), (20, 'soap'), (15, 'rug'), (25, 'apple'), (25, 'banana')]
Run Code Online (Sandbox Code Playgroud)

订单与预期的输出不同,但数字与名称匹配,这就是重点.如果你想要相同的订单,只需删除第一个项目(列表中的性能较低,所以如果你有选择,最好在列表中插入和删除最后一个项目,它会更快):

result = [(i,d[i].pop(0)) for i in sequence]
Run Code Online (Sandbox Code Playgroud)

得到:

[(25, 'banana'), (15, 'rug'), (20, 'soap'), (15, 'cloud'), (25, 'apple'), (25, 'pine')]
Run Code Online (Sandbox Code Playgroud)