4

我得到一个列表,我通过以下方式保存结果

City Percentage
Mumbai  98.30
London 23.23
Agra    12.22
.....

列表结构为 [["Mumbai",98.30],["London",23.23]..]

我以列表的形式保存这些记录。我需要将列表排序为 top_ten 记录。即使我也得到城市,也可以。

我正在尝试使用以下逻辑,但无法提供准确的数据

if (condition):
    if b not in top_ten:
        top_ten.append(b)   
        top_ten.remove(tmp)

任何其他解决方案,方法也是受欢迎的。

编辑 1

for a in sc_percentage:
            print a

我得到的清单

(<ServiceCenter: DELHI-DLC>, 100.0)
(<ServiceCenter: DELHI-DLE>, 75.0)
(<ServiceCenter: DELHI-DLN>, 90.909090909090907)
(<ServiceCenter: DELHI-DLS>, 83.333333333333343)
(<ServiceCenter: DELHI-DLW>, 92.307692307692307)
4

4 回答 4

7

如果列表很短,那么正如其他人建议的那样,您可以对其进行排序和切片。如果列表非常大,那么您最好使用heapq.nlargest()

>>> import heapq
>>> lis = [['Mumbai', 98.3], ['London', 23.23], ['Agra', 12.22]]
>>> heapq.nlargest(2, lis, key=lambda x:x[1])
[['Mumbai', 98.3], ['London', 23.23]]

不同之处在于 nlargest 仅通过列表一次,事实上,如果您正在从文件或其他生成的源中读取,则不必同时都在内存中。

您可能也有兴趣查看源代码,nlargest()因为它的工作方式与您尝试解决问题的方式大致相同:它仅在称为堆的数据结构中保留所需数量的元素,并且推送每个新值进入堆,然后从堆中弹出最小值。

编辑以显示比较时间

>>> import random
>>> records = []
>>> for i in range(100000):
    value = random.random() * 100
    records.append(('city {:2.4f}'.format(value), value))


>>> import heapq
>>> heapq.nlargest(10, records, key=lambda x:x[1])
[('city 99.9995', 99.99948904248298), ('city 99.9974', 99.99738898315216), ('city 99.9964', 99.99642759230214), ('city 99.9935', 99.99345173704319), ('city 99.9916', 99.99162694442714), ('city 99.9908', 99.99075084123544), ('city 99.9887', 99.98865134685201), ('city 99.9879', 99.98792632193258), ('city 99.9872', 99.98724339718686), ('city 99.9854', 99.98540548350132)]
>>> timeit.timeit('sorted(records, key=lambda x:x[1])[:10]', setup='from __main__ import records', number=10)
1.388942152229788
>>> timeit.timeit('heapq.nlargest(10, records, key=lambda x:x[1])', setup='import heapq;from __main__ import records', number=10)
0.5476185073315492

在我的系统上,通过排序和切片从 100 条记录中获得前 10 条是最快的,但是对于 1000 条或更多记录,使用 nlargest 更快。

于 2013-06-25T11:26:28.930 回答
5

首先对列表进行排序,然后对其进行切片:

>>> lis = [['Mumbai', 98.3], ['London', 23.23], ['Agra', 12.22]]
>>> print sorted(lis, key = lambda x : x[1], reverse = True)[:10] #[:10] returns first ten items
[['Mumbai', 98.3], ['London', 23.23], ['Agra', 12.22]]

要从该文件中以列表形式获取数据,请使用以下命令:

with open('abc') as f:
    next(f)  #skip header 
    lis = [[city,float(val)]  for city, val in( line.split() for line in f)]
    print lis 
    #[['Mumbai', 98.3], ['London', 23.23], ['Agra', 12.22]]  

更新:

new_lis = sorted(sc_percentage, key = lambda x : x[1], reverse = True)[:10]
for item in new_lis:
   print item

sorted返回一个新的排序列表,因为我们需要根据每个元素的第二项对列表进行排序,所以我们使用了key参数。

key = lambda x : x[1]表示使用每个项目的索引 1 上的值(即 100.0、75.0 等)进行比较。

reverse= True用于反向排序。

于 2013-06-25T10:39:18.287 回答
2

您必须将输入转换为 Python 可以轻松处理的内容:

with open('input.txt') as inputFile:
    lines = inputFile.readLines()
records = [ line.split() for line in lines ]
records = [ float(percentage), city for city, percentage in records ]

现在records包含这样的条目列表:

[ [ 98.3, 'Mumbai' ], [ 23.23, 'London' ], [ 12.22, Agra ] ]

您可以就地对该列表进行排序:

records.sort()

您可以通过切片打印前十名:

print records[0:10]

如果您有一个巨大的列表(例如数百万个条目)并且只想以排序的方式将其中的前十名排序,那么有比对整个列表进行排序更好的方法(那样会浪费时间)。

于 2013-06-25T10:43:55.190 回答
1

要打印前 10 个城市,您可以使用:

首先对列表进行排序,然后对其进行切片:

>>> lis = [['Mumbai', 98.3], ['London', 23.23], ['Agra', 12.22]]
>>> [k[0] for k in sorted(lis, key = lambda x : x[1], reverse = True)[:10]]
    ['Mumbai', 'London', 'Agra']

对于给定的列表

 >>>: lis=[("<ServiceCenter: DELHI-DLC>", 100.0),("<ServiceCenter: DELHI-DLW>", 92.307692307692307),("<ServiceCenter: DELHI-DLE>", 75.0),("<ServiceCenter: DELHI-DLN>", 90.909090909090907),("<ServiceCenter: DELHI-DLS>", 83.333333333333343)]

 >>>:t=[k[0] for k in sorted(lis, key = lambda x : x[1], reverse = True)[:10]]
 >>>:print t
['<ServiceCenter: DELHI-DLC>',
'<ServiceCenter: DELHI-DLW>',
'<ServiceCenter: DELHI-DLN>',
'<ServiceCenter: DELHI-DLS>',
'<ServiceCenter: DELHI-DLE>']

Sorted 函数返回以 key 作为比较函数的排序列表。

于 2013-06-25T10:46:39.577 回答