鱼C论坛

 找回密码
 立即注册
查看: 1210|回复: 7

[已解决]请教一个列表排序问题

[复制链接]
发表于 2022-1-26 13:45:36 | 显示全部楼层 |阅读模式
20鱼币
本帖最后由 去冰无糖 于 2022-1-26 13:44 编辑

仍在学习排序问题中,我碰到的问题几句话难以表达清楚,故借助一个我自己假想的排序问题来展现,题目如下:

给定一个整数列表nums,其中只包含a,b,c三种元素,即满足len(nums)==nums.count(a)+nums.count(b)+nums.count(c)
a,b,c的数量满足a<=b<=c,返回一个按照b,c,a的顺序排列的列表,即[b,c,a,b,c,a,b,c,a……],若因a,b,c的数量不足以满足b,c,a,则忽略数量不足的元素继续排列。
-----------------------------------------------------------------------------------------------
举例:
nums = [1,1,1,1,2,2,2,3,3],即a = 1,b = 2,  c = 3
返回[2,1,3,2,1,3,2,1,1]  第3个2,1,3由于3的数量不足,只排列2,1;第4个2,1,3由于2,3的数量不足,只排列1。
-----------------------------------------------------------------------------------------------
代码要求
1.代码尽可能的精炼,简洁,完全不考虑时间复杂度,空间复杂度那些作为我这个小白暂时还鞭长莫及的领域。我想要的不是任意一种解法,而是通过努力达到一行流的这种方式训练自己对各种思维、方法、函数、参数的理解。
2.就以上述nums = [1,1,1,1,2,2,2,3,3],a = 1,b = 2,  c = 3 为例子编写代码即可,我在意的是解法本身及背后的思维。
3.没有其他任何限制,但最好只使用python基本库。
------------------------------------------------------------------------------------------------
先感谢各位大佬的不啬赐教!
最佳答案
2022-1-26 13:45:37
去冰无糖 发表于 2022-1-26 16:38
我觉得您的答案可能很符合我的期望了,虽然核心代码根本看不懂,因为不懂itertools这个库,我自己再去学 ...

我加上注释吧。
import itertools  #为了引入zip_longest函数
nums = [1,1,1,1,2,2,2,3,3]
a = 1
b = 2
c = 3
num_a = [a] * nums.count(a) #根据a, b, c的数量建立新的列表
num_b = [b] * nums.count(b)
num_c = [c] * nums.count(c)
new = itertools.zip_longest(num_b, num_c, num_a) #内置函数zip是将多个参数(必须是可迭代的,如列表、元组等)的第一个元素组成一个元素,第二个、第三个依次,直到最短的参数结束为止,改用.zip_longest,是因为它可以以最长的参数为准,不足的用None补齐
new = list(filter(None, sum(new, tuple()))) #sum的一个偏门用法,将子元组拼接到一起,形成一个一维的结构,再用list转换为列表,
print(new)

最佳答案

查看完整内容

我加上注释吧。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-26 13:45:37 | 显示全部楼层    本楼为最佳答案   
去冰无糖 发表于 2022-1-26 16:38
我觉得您的答案可能很符合我的期望了,虽然核心代码根本看不懂,因为不懂itertools这个库,我自己再去学 ...

我加上注释吧。
import itertools  #为了引入zip_longest函数
nums = [1,1,1,1,2,2,2,3,3]
a = 1
b = 2
c = 3
num_a = [a] * nums.count(a) #根据a, b, c的数量建立新的列表
num_b = [b] * nums.count(b)
num_c = [c] * nums.count(c)
new = itertools.zip_longest(num_b, num_c, num_a) #内置函数zip是将多个参数(必须是可迭代的,如列表、元组等)的第一个元素组成一个元素,第二个、第三个依次,直到最短的参数结束为止,改用.zip_longest,是因为它可以以最长的参数为准,不足的用None补齐
new = list(filter(None, sum(new, tuple()))) #sum的一个偏门用法,将子元组拼接到一起,形成一个一维的结构,再用list转换为列表,
print(new)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-26 14:19:52 From FishC Mobile | 显示全部楼层
这样可以?
arr = [1, 1, 1, 1, 2, 2, 2, 3, 3]
c, b, a = sorted(list(set(arr)), key = lambda x: arr.count(x))
x, y, z = arr.count(a), arr.count(b), arr.count(c)
res = []
for i in range(len(arr)):
        if(y):
                res.append(b)
                y -= 1
        if(z):
                res.append(c)
                z -= 1
        if(x):
                res.append(a)
                x -= 1
print(res)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-26 14:50:56 | 显示全部楼层

可是你这里用了 set() 函数不就无法判断他们分别在列表里占的个数了吗?
你这样做最后比的是值的大小,而不是根据值在列表中占的位置去比,题目要求的是:
a,b,c的数量满足a<=b<=c

这里写的是数量,而不是比较对象本身,所以不能用 set() 方法去掉重复的,
这恰巧是最关键的......我已被难住了...

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-26 14:52:04 | 显示全部楼层
python爱好者. 发表于 2022-1-26 14:50
可是你这里用了 set() 函数不就无法判断他们分别在列表里占的个数了吗?
你这样做最后比的是值的大小, ...

哎?不对!好像是我理解错了...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-26 15:37:15 | 显示全部楼层
换个思路写一个
import itertools
nums = [1,1,1,1,2,2,2,3,3]
a = 1
b = 2
c = 3
num_a = [a] * nums.count(a)
num_b = [b] * nums.count(b)
num_c = [c] * nums.count(c)
new = itertools.zip_longest(num_b, num_c, num_a)
new = list(filter(None, sum(new, tuple())))
print(new)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-1-26 16:31:10 | 显示全部楼层
按我自己期望的解法,是将a,b,c三个元素构成的b,c,a这种序列作为一个参数传入某个函数,这个函数根据[b,c,a]设定的规则,将nums直接转换为想要的列表,那么这种解法就能够适用于a,b,c,d……等任意个元素的任意排列方式,不知道是否能够实现。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-1-26 16:38:02 | 显示全部楼层

我觉得您的答案可能很符合我的期望了,虽然核心代码根本看不懂,因为不懂itertools这个库,我自己再去学习学习,如果确实是我想要的,且没有更简洁的解法,那么拟将您的解法设为最佳答案,谢谢您的指点!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-12 10:05

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表