如何先按我想要的内容排序列表,然后按字母顺序排序

How to sort list by what I want first, then by alphabetical order

提问人:Eusto 提问时间:10/27/2023 最后编辑:greybeardEusto 更新时间:10/29/2023 访问量:174

问:

这是两个列表,它们相互关联

fruits = ['watermelon','orange', 'pear', 'mango', 'apple', 'grapes']
values = [3, 5, 2, 3, 2, 4]

我希望先有'葡萄'、'橙子'、'苹果',然后是其余的按字母顺序排列。

最终名单:

new_fruits = ['grapes', 'orange', 'apple', 'mango', 'pear', 'watermelon' ]
new_values = [4, 5, 2, 3, 2, 3]

我怎样才能做到这一点?

我使用了 .sort(),但这只能帮助按字母顺序排序,而不是按我首先想要的内容排序。

python 数组 列表 排序 lambda

评论

0赞 Grismar 10/27/2023
你是在乎 的顺序,还是只想让这三个人按任何顺序排在第一位?如果有多个 、 或 '?应该把所有这些东西都放在第一位,还是你只需要一个,其余的应该按字母顺序排序?'grapes', 'orange', 'apple''grapes''orange''apple
0赞 Mark Ransom 10/27/2023
独立对这两个列表进行排序是很困难的,最好创建一个元组列表,然后在需要时将其拆分。
0赞 CtrlZ 10/27/2023
这不是真正的一种排序 - 这是一种重新排列。值对之间没有有序的关系
0赞 Mark Ransom 10/29/2023
我不同意识别的重复项确实是重复项,这个问题还有其他复杂性。
0赞 Mark Ransom 10/29/2023
哇,我忘了骗子锤子是双向的。

答:

0赞 Mark Ransom 10/27/2023 #1

要将两个列表排序在一起,您应该将它们合并为一个列表,然后将它们分开。

combined = list(zip(fruits, values))
sorted_list = sorted(combined)
new_fruits = [item[0] for item in sorted_list]
new_values = [item[1] for item in sorted_list]

现在,您只需要使用参数来获得正确的顺序。keysorted

d = {'grapes':0, 'orange':1, 'apple':2}
tail = max(d.values()) + 1
def key_func(item):
    return (d.get(item[0], tail), item[0])
sorted_list = sorted(combined, key=key_func)

返回一个元组,该元组由一个整数组成,用于对优先级项进行排序,后跟输入元组的第一部分,即水果名称。Python 的排序将使用元组键,根据元组的每个元素按顺序排序,因此首先按优先级代码排序,然后按名称排序。key_func

评论

0赞 Mark Ransom 10/27/2023
@sahasrara62我还在努力解决这个问题。我看到关于这个问题的一些接近的投票,所以我想在那之前发布一个答案。
0赞 dmitri 10/27/2023
Mark,您可以使用更简单的 lambda:sorted_list = sorted(combined, key=lambda item:d.get(item[0]) or item[0])
0赞 Abdul Aziz Barkat 10/27/2023
键函数返回的值可以是元组。因此,您可以将葡萄、橙子和苹果映射到一个数字,将其他所有东西映射到另一个数字,然后返回该数字和字符串本身。这样做的好处是不依赖于某些未出现的字符,并且很明显有两个排序标准。
0赞 Mark Ransom 10/29/2023
@AbdulAzizBarkat这是一个很好的建议,我现在已经实施了。当我第一次写答案时,我实际上想到了同样的事情,但正如我之前所说,我很匆忙。
0赞 sahasrara62 10/27/2023 #2

你可以使用这样的东西

>>> new_fruits = ['grapes', 'orange', 'apple', 'mango', 'pear', 'watermelon','apple' ]
>>> new_values = [4, 5, 2, 3, 2, 3, 6]
>>> l = list(zip(new_fruits, new_values))
>>> order = [ 'grapes', 'orange', 'apple']
>>> result = sorted(l, key=lambda x: (x[0] not  in order))
>>> new_sorted_fruits = [i[0] for i in result]
>>> new_sorted_values = [i[1] for i in result]
>>> new_sorted_fruits
['grapes', 'orange', 'apple', 'apple', 'mango', 'pear', 'watermelon']
>>> new_sorted_values
[4, 5, 2, 6, 3, 2, 3]

评论

0赞 dmitri 10/27/2023
您的 lambda 不正确,您不会以这种方式对列表的尾部进行排序。
0赞 Suramuthu R 10/27/2023 #3
def mySorting(fruits, values, first_few_items):
    dct = {fruits[i]:values[i] for i in range(len(fruits))}
    new_fruits = [x for x in fruits if x not in first_few_items]
    new_fruits.sort()
    new_fruits = first_few_items + new_fruits
    new_values = [dct[x] for x in new_fruits]
    return(new_fruits, new_values)

fruits = ['watermelon','orange', 'pear', 'mango', 'apple', 'grapes']
values = [3,5,2,3,2,4]
first_few_items = ['grapes', 'orange', 'apple']
r = mySorting(fruits, values, first_few_items)
print(r)

#output:
(['grapes', 'orange', 'apple', 'mango', 'pear', 'watermelon'], [4, 5, 2, 3, 2, 3])

在上面的代码中,前几项不仅限于三个。您可以根据需要添加任意数量。

0赞 blhsing 10/27/2023 #4

鉴于:

fruits = ['watermelon', 'orange', 'pear', 'mango', 'apple', 'grapes']
values = [3, 5, 2, 3, 2, 4]
firsts = ['grapes', 'orange', 'apple']

您可以创建一个映射字典,将水果名称映射到相应的值,以及另一个映射,将水果名称映射到其各自的索引以进行排序:mappingindexfirsts

mapping = dict(zip(fruits, values))
index = dict(map(reversed, enumerate(firsts)))

您可以使用一个键函数进行排序,该函数返回一个元组,其中第一项是水果的值(如果可以找到),或者是无穷大,使水果进入后一组,第二项是水果的名称,按字母顺序排序。 然后是映射的值:fruitsindexnew_valuesnew_fruitsmapping

new_fruits = sorted(fruits, key=lambda k: (index.get(k, float('inf')), k))
new_values = list(map(mapping.get, new_fruits))

因此:

print(new_fruits)
print(new_values)

输出:

['grapes', 'orange', 'apple', 'mango', 'pear', 'watermelon']
[4, 5, 2, 3, 2, 3]

演示:https://ideone.com/oxeCRu

评论

0赞 Abdul Aziz Barkat 10/27/2023
如果有任何重复项,这将不起作用(它会静默地丢弃它们)。
0赞 blhsing 10/27/2023
然后针对这种可能性进行了更新。
0赞 CtrlZ 10/27/2023 #5

不一定是最有效的解决方案,但显示了一种清晰的分步方法。

fruits = ["watermelon", "orange", "pear", "mango", "apple", "grapes"]
values = [3, 5, 2, 3, 2, 4]

# create a sorted list of tuples (fruit/value) pairs
# natural sort
temp = sorted(zip(fruits, values))

# note how the fruit names are in reverse order
for fruit in "apple", "orange", "grapes":
    for i, (f, v) in enumerate(temp.copy()):
        if f == fruit:
            del temp[i]
            temp.insert(0, (f, v))
            break

new_fruits = [f for f, _ in temp]
new_values = [v for _, v in temp]

print(new_fruits)
print(new_values)

输出:

['grapes', 'orange', 'apple', 'mango', 'pear', 'watermelon']
[4, 5, 2, 3, 2, 3]
0赞 cards 10/27/2023 #6

作为单一排序。

请注意(字符串中的数字小于字母字符)。'682190'<'a'

# [added some more fruits]
fruits = ['zfruit', 'ananas', 'watermelon','orange', 'pear', 'mango', 'apple', 'banana', 'grapes']
values = [0,0,3,5,2,3,2,0,4]

# exception of the order
first_fruits = 'grapes', 'orange', 'apple'

new_fruits, new_values = \
    zip(*sorted(zip(fruits, values),
                key=lambda x: (
                    str(first_fruits.index(x[0]))
                    if x[0] in first_fruits
                    else x[0]
                    )
    ))
print(new_fruits)
#('grapes', 'orange', 'apple', 'ananas', 'banana', 'mango', 'pear', 'watermelon', 'zfruit')
print(new_values)
#(4, 5, 2, 0, 0, 3, 2, 3, 0)

使用内置函数。请注意,

  1. 字典可以从表单的元组列表中生成(key, value)
  2. 可以通过 ping 到列表来生成表单的元组列表,一个用于键,一个用于值。进一步应用1.你可以从他们那里得到(key, value)zipdict
  3. 带有一些常用键的链式词典保持插入顺序
fruits = ['watermelon','orange', 'pear', 'mango', 'apple', 'grapes']
values = [3,5,2,3,2,4]

# exception of the order
first_fruits = 'grapes', 'orange', 'apple'

# initial order for exceptions
tmp_sorted = dict.fromkeys(first_fruits)

# sort all data alphabetically & add sorted fruits
tmp_sorted.update(sorted(zip(fruits, values)))

# decouple keys and values
new_fruits, new_values = zip(*tmp_sorted.items())
print(new_fruits, new_values)