在Python

时间:2017-05-21 18:41:18

标签: python list sorting

我有一个看起来像这样的列表。 [0,0,0,0,0,'entrya',5,'entryb',10,'anotherentry',7,'entry',1,'entryd',30,....,0,0, 0,0,0,0]

等等,我认为这个想法很明确。我现在的问题是我想在与字符串相关联的数字之后对整个列表进行排序。所以结果看起来像这样。 ['entry',1,'entrya',5,'anotherentry',7,'entryb',10,'entryd',30,...... 0,0,0,0,0(或其他方式)回合,什么会更好。)

我的问题显然是相邻的条目必须保持在一起,并且不允许使用字典进行此练习。

有人知道如何做到这一点吗?

非常感谢!

4 个答案:

答案 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]

答案 1 :(得分:0)

我的方法是首先将列表中的元素压缩为元组,如下所示:

[('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]

答案 2 :(得分:0)

这看起来像一个非常奇怪的数据集,但假设你确实需要这个: 如果您在开头和结尾删除0,那么排序相当容易:

>>> 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作为其他entries的值,那么您可以将其作为2个案例处理,将所有内容排成零,然后加回所有零。

>>> 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]

答案 3 :(得分:0)

您可以使用reduce模块中的functools,来自addoperatorzip的{​​{1}}来获得所需的输出。

NB:

在此解决方案中:

  • 您需要解析输入列表并从中分离零。
  • 然后,根据第二个元素
  • 从数据中创建一对,而不包含零
  • 最后将step2与step1的零列表连接起来

这是一个例子:

sorted()

输出:

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)