在Python中使用两种不同类型对列表进行排序
我有一张这样的清单。[0,0,0,0,0,'entrya',5,'entryb',10,'anotherentry',7,'entry',1,'entryd',30,…,0,0,0,0] 等等,我认为这个想法很清楚。我现在的问题是,我想在与字符串关联的数字之后对整个列表进行排序。结果是这样的。[entry',1',entrya',5',anotherentry',7',entryb',10',entryd',30,.0,0,0,0](或者反过来说,还有什么更好的选择。) 很明显,我的问题是相邻的词条必须放在一起,而且不允许使用字典进行此练习 有人知道怎么做吗在Python中使用两种不同类型对列表进行排序,python,list,sorting,Python,List,Sorting,我有一张这样的清单。[0,0,0,0,0,'entrya',5,'entryb',10,'anotherentry',7,'entry',1,'entryd',30,…,0,0,0,0] 等等,我认为这个想法很清楚。我现在的问题是,我想在与字符串关联的数字之后对整个列表进行排序。结果是这样的。[entry',1',entrya',5',anotherentry',7',entryb',10',entryd',30,.0,0,0,0](或者反过来说,还有什么更好的选择。) 很明显,我的问题是相邻的
多谢各位 我不太确定我是否理解您的原始列表是如何构建的。如果我们称它为
x
,并且每个偶数项(0,2,…)都是一个字符串,每个奇数项(1,3,…)都是与前面的字符串关联的数字,则可以将其转换为元组列表,如下所示:
y = zip(x[0::2], x[1::2])
然后可以对元组y的列表进行排序:
y.sort(key=lambda t: t[1])
这将产生:
[(0, 0),
(0, 0),
(0, 0),
(0, 0),
(0, 0),
(0, 0),
('entry', 1),
('entrya', 5),
('anotherentry', 7),
('entryb', 10),
('entryd', 30)]
这有用吗
编辑:
要再次将其展平为列表,请执行以下操作:
z = [entry for tup in y for entry in tup]
我的方法是先将列表中的元素压缩为元组,如下所示:
[('null', 0), ('null', 0), ('null', 0), ('entrya', 5), ('entryb', 10), ('anotherentry', 7), ...]
之后,可以按第二个元素对元素进行排序
ls = [0, 0, 0, 0, 0, 'entrya', 5, 'entryb', 10, 'anotherentry', 7,
'entry', 1, 'entryd', 30, 0, 0, 0, 0, 0, 0]
ls_zip_elem = []
for x1, x2 in zip(ls, ls[1:]):
if x1 == 0:
ls_zip_elem.append(('null', x1))
elif not str(x1).isdigit():
ls_zip_elem.append((x1, x2))
else:
pass
ls_zip_elem_sorted = sorted(ls_zip_elem, key=lambda x: x[1]) # sorted
# put the list back
ls_sorted = []
for x1, x2 in ls_zip_elem_sorted:
if x1 == 'null':
ls_sorted.append(x2)
else:
ls_sorted.extend([x1, x2])
# output
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'entry', 1, 'entrya', 5, 'anotherentry', 7,
# 'entryb', 10, 'entryd', 30]
这似乎是一个非常奇怪的数据集,但假设您真的需要它:
如果删除开头和结尾的
0
s,则排序相当容易:
>>> l = ['entrya', 5, 'entryb', 10, 'anotherentry', 7, 'entry', 1, 'entryd', 30]
>>> [b for a in sorted(zip(*[iter(l)]*2), key=lambda x: x[1]) for b in a]
['entry', 1, 'entrya', 5, 'anotherentry', 7, 'entryb', 10, 'entryd', 30
因此,假设您没有0
作为其他条目的值,那么您可以将其作为两种情况处理,对所有内容进行排序,而不是成对地归零,然后将所有的零相加
>>> l = [0,0,0,0,0,'entrya',5, 'entryb', 10, 'anotherentry', 7, 'entry', 1, 'entryd', 30, 0,0,0,0,0]
>>> pairs = [b for a in sorted(zip(*[iter(filter(lambda x: x!=0, l))]*2), key=lambda x: x[1]) for b in a]
>>> zeros = list(filter(lambda x: x == 0, l))
>>> pairs + zeros
['entry', 1, 'entrya', 5, 'anotherentry', 7, 'entryb', 10, 'entryd', 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
您可以使用functools
模块中的reduce
、操作符中的add
、zip
和sorted()
获得所需的输出
注意:
在此解决方案中:
- 你需要解析你的输入列表,并从中分离出零
- 然后,基于第二个元素从数据中创建一对,其中不包含零
- 最后,将步骤2与步骤1的零列表连接起来
这是一个例子:
from operator import add
from functools import reduce
data = [0,0,0,0,0,'entrya',5, 'entryb', 10, 'anotherentry', 7, 'entry', 1, 'entryd', 30, 0,0,0,0,0,0]
non_zeros, zeros = [k for k in data if k is not 0], [0]*data.count(0)
pairs = [[k,v] for k,v in zip(non_zeros[::2], non_zeros[1::2])]
final = reduce(add, sorted(pairs, key= lambda x: x[1])) + zeros
print(final)
输出:
['entry', 1, 'entrya', 5, 'anotherentry', 7, 'entryb', 10, 'entryd', 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
从列表中创建元组,然后对元组排序,然后展平列表。但是在开始和结束时没有关联,只有0.0…为什么从结果中遗漏了'entrya',5
。Edited如何从列表中创建元组?开头有奇数个零,所以这不起作用。@我想可能缺少一个元组。如果这个列表实际上是一个成对的列表,那么它有一个合理的结构。如果它只是一个任意数量的零,实际上不携带任何信息,那么我建议首先找到数据的另一种表示形式。不,它工作得很好,奇数个零是我的错,对不起。它应该是偶数个零