在Python中使用两种不同类型对列表进行排序

在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](或者反过来说,还有什么更好的选择。) 很明显,我的问题是相邻的

我有一张这样的清单。[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如何从列表中创建元组?开头有奇数个零,所以这不起作用。@我想可能缺少一个元组。如果这个列表实际上是一个成对的列表,那么它有一个合理的结构。如果它只是一个任意数量的零,实际上不携带任何信息,那么我建议首先找到数据的另一种表示形式。不,它工作得很好,奇数个零是我的错,对不起。它应该是偶数个零