对包含列表的列表进行排序

时间:2012-07-06 14:21:39

标签: python list sorting dictionary

我有一个生成包含未知数量子列表的列表的算法,每个子列表具有未知数量的字符串元素以及一个浮点数。我需要根据这个浮点数在主列表中排序这些子列表。此外,不会重新排列子列表中字符串的顺序。

我目前正在运行一段代码(下面链接),使用dict对其进行排序。你可以看到我正在获得KeyErrors。我之前没有使用过dicts,所以我不知道从哪里开始。如果有一个更好的方式,那么一个词也可以打开。 http://ideone.com/wr8UA

花车不是顺序的,我不知道这是多大的交易,这是使用我有的方法。意思是,偶尔会跳过数字(在Ideone的示例列表中,它们是1.0,2.0,4.0;跳过3.0以在运行时模拟这种情况)。它们也不在子列表中的任何特定位置,因此所有for循环都在搜索它们。

希望这很清楚,我之前尝试过这样做,然后得到了回报,而不是关于什么让人感到困惑的问题。如果有什么不对劲,请告诉我。谢谢大家!

编辑:请求正文中的代码:

listed = [ ["1 NWZ", "1 RWZ", "2 NWZ", "2 RWZ", "1E HZ", "1W HZ", "1-2EHZ", 2.0, "2W HZ"],
["1 NWZ", "1W HZ", "3E FZ", "SNOK", "POK", 3.0, "1-2EHZ", "2E AK", "2W HZ"],
["1 BW", "1AW AS", "3E FZ", "1BWAK", "POK", "TESTK", "1-2EHZ", "2E AK", 1.0]] 

dictionary={}
for sub_list in listed:
    for value in sub_list:
        if isinstance(value,float):
            dictionary[str(value)]=sub_list
        else:
            pass
ordered_list=[]
    for i in range(1,len(listed)+1):
    if dictionary[str(i)]:
        ordered_list.append(dictionary[str(i)])

for sub_list in ordered_list:
    print sub_list

6 个答案:

答案 0 :(得分:9)

sort method有一个方便的key关键字参数,让您指定一个函数来调用以确定列表应该排序的信息。

对列表进行排序就像编写一个返回每个子列表中包含的浮点值的函数一样简单:

def sortOnFloat(sublist):
    return [v for v in sublist if isinstance(v, float)]

请注意,我只返回所有浮点值的list;比只返回一个容易得多。即使子列表中有0个浮点值,这也会起作用。

按如下方式对列表进行排序:

listed.sort(key=sortOnFloat)

我克隆了您的示例并使用上述方法更新了它:http://ideone.com/u8ufK

生成的输出:

['1 BW', '1AW AS', '3E FZ', '1BWAK', 'POK', 'TESTK', '1-2EHZ', '2E AK', 1.0]
['1 NWZ', '1 RWZ', '2 NWZ', '2 RWZ', '1E HZ', '1W HZ', '1-2EHZ', 2.0, '2W HZ']
['1 NWZ', '1W HZ', '3E FZ', 'SNOK', 'POK', 3.0, '1-2EHZ', '2E AK', '2W HZ']

请注意.sort()方法就地对列表进行排序。您还可以使用sorted() function生成已排序的新列表;它需要相同的论点:

orderedlist = sorted(listed, key=sortOnFloat)

但请注意,就地排序总是更快。

答案 1 :(得分:2)

创建一个函数来提取要对其进行排序的键,然后调用sorted

listed = [ ["1 NWZ", "1 RWZ", "2 NWZ", "2 RWZ", "1E HZ", "1W HZ", "1-2EHZ", 2.0, "2W HZ"],
["1 NWZ", "1W HZ", "3E FZ", "SNOK", "POK", 3.0, "1-2EHZ", "2E AK", "2W HZ"],
["1 BW", "1AW AS", "3E FZ", "1BWAK", "POK", "TESTK", "1-2EHZ", "2E AK", 1.0]] 

def get_key(l):
    return next(e for e in l if type(e) is float)

print sorted(listed, key=get_key)

答案 2 :(得分:1)

也许这个链接可以帮助你,这提供了几乎所有语言都实现自定义排序的方法。

Sort using a custom comparator

答案 3 :(得分:0)

您收到错误,因为列表中的数字是浮点数,但您使用整数查找键:

listed = [ ["1 NWZ", "1 RWZ", "2 NWZ", "2 RWZ", "1E HZ", "1W HZ", "1-2EHZ", 2.0, "2W HZ"],
["1 NWZ", "1W HZ", "3E FZ", "SNOK", "POK", 3.0, "1-2EHZ", "2E AK", "2W HZ"],
["1 BW", "1AW AS", "3E FZ", "1BWAK", "POK", "TESTK", "1-2EHZ", "2E AK", 1.0]]

dictionary={}
for sub_list in listed:
    for value in sub_list:
        if isinstance(value,float):  #### you look for floats
            dictionary[str(value)]=sub_list   ### the key is created as string
        else:
            pass
ordered_list=[]
for i in range(1,len(listed)+1):   ### this is a range of INTS!!!!
    if dictionary[str(i)]:
        ordered_list.append(dictionary[str(i)])  #### str(i) is '1', not '1.0' 

for sub_list in ordered_list:
    print sub_list

我只能认为这不是好代码。首先,不应在同一列表中混合使用字符串和数字。如果您创建该列表,我建议您使用dict,例如:

listitem = {'number': 2.0, 'strings': ['1 NHZ', '1 RWZ', 'TESTK']}

希望这有帮助!

答案 4 :(得分:0)

>>> listed = [ ["1 NWZ", "1 RWZ", "2 NWZ", "2 RWZ", "1E HZ", "1W HZ", "1-2EHZ", 2.0, "2W HZ"],
["1 NWZ", "1W HZ", "3E FZ", "SNOK", "POK", 3.0, "1-2EHZ", "2E AK", "2W HZ"],
["1 BW", "1AW AS", "3E FZ", "1BWAK", "POK", "TESTK", "1-2EHZ", "2E AK", 1.0]]
>>> listed
[['1 NWZ', '1 RWZ', '2 NWZ', '2 RWZ', '1E HZ', '1W HZ', '1-2EHZ', 2.0, '2W HZ'], ['1 NWZ', '1W HZ', '3E FZ', 'SNOK', 'POK', 3.0, '1-2EHZ', '2E AK', '2W HZ'], ['1 BW', '1AW AS', '3E FZ', '1BWAK', 'POK', 'TESTK', '1-2EHZ', '2E AK', 1.0]]
>>> dictionary ={}
>>> for index,sub_list in enumerate(listed):
    for value in sub_list:
        if isinstance(value,float):
            dictionary[value]=index
        else:
            pass


>>> dictionary
{1.0: 2, 2.0: 0, 3.0: 1}
>>> it = sorted(dictionary.items())
>>> it
[(1.0, 2), (2.0, 0), (3.0, 1)]
>>> ordered_list = []
>>> for item in it:
    ordered_list.append(listed[item[1]])


>>> ordered_list
[['1 BW', '1AW AS', '3E FZ', '1BWAK', 'POK', 'TESTK', '1-2EHZ', '2E AK', 1.0], ['1 NWZ', '1 RWZ', '2 NWZ', '2 RWZ', '1E HZ', '1W HZ', '1-2EHZ', 2.0, '2W HZ'], ['1 NWZ', '1W HZ', '3E FZ', 'SNOK', 'POK', 3.0, '1-2EHZ', '2E AK', '2W HZ']]
>>> 

答案 5 :(得分:0)

您的错误来自您的代码中没有'1'元素。它实际上是'1.0'(因为它是一个浮点数),这样做会使代码工作:

for i in range(1,len(listed)+1):
    if dictionary[str(float(i))]:
        ordered_list.append(dictionary[str(float(i))])

然而,在我看来,这远远不是你想要做的事情的好方法,而且很多人都为替代方案提供了很好的建议。