3

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

我目前通过一大块代码(链接如下)运行它,它使用字典对其进行排序。如您所见,我收到了 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
4

6 回答 6

9

sort方法有一个方便的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()函数生成一个已排序的新列表;它采用相同的论点:

orderedlist = sorted(listed, key=sortOnFloat)

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

于 2012-07-06T14:26:31.423 回答
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)
于 2012-07-06T14:26:37.103 回答
1

也许这个链接可以帮助你,它提供了在几乎每种语言中实现自定义排序的方法。

使用自定义比较器进行排序

于 2012-07-06T14:28:40.270 回答
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

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

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

希望这可以帮助!

于 2012-07-06T14:26:35.767 回答
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']]
>>> 
于 2012-07-06T14:34:52.750 回答
0

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

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

然而,在我看来,这远不是一个做你想做的事情的好方法,许多人对替代方案给出了很好的建议。

于 2012-07-06T14:36:38.093 回答