关于打印列表前9个对象的查询

2024-10-06 12:29:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要创建一个函数,根据给定的数据,它确定特定河流的监测站数量。然后,此函数需要返回(河流名称,站点数)元组列表中的前N个对象,这些元组按站点数降序排序

然而,一些河流可能具有相同数量的站点,这些站点需要被视为返回列表中的一个条目,但我不确定如何才能做到这一点。(返回的列表可能有N个以上的对象,但只有N个数字…如果有意义的话)

到目前为止,我创建的函数如下:

def rivers_by_station_number(stations, N):

    riv_names = set()
    for station in stations:
        riv_names.add(station.river)

    num_stations = []
    for name in riv_names:
        n = 0
        for station in stations:
            if station.river == name:
                n += 1
            else:
                pass

        num_stations.append(n)

    lst_tuple = list(zip(riv_names, num_stations))
    lst_tuple_sort = sorted(lst_tuple, key=lambda x: x[1], reverse=True)

    return lst_tuple_sort[:N]

是否有一个排序函数,我可以返回排序列表的前N个对象,同时将相同的数字视为单数条目

额外信息

当我运行函数时,其中N=9,我得到以下结果:

[('River Thames', 55), ('River Avon', 32), ('River Great Ouse', 30), ('River Derwent', 25), ('River Aire', 24), ('River Calder', 22), ('River Severn', 21), ('River Stour', 19), ('River Ouse', 18)]

因此,幸运的是,排序列表中前9个对象中没有一条河流具有相同数量的监测站,但是,我仍然希望在我的函数中实现上述功能,因为数据总是在变化

非常感谢你


Tags: 对象函数列表for数量names排序站点
2条回答

你的代码效率不高,首先我会优化它:

def rivers_by_station_number(stations, N):

    river_station = {}
    for station in stations:
        river_station[station.river] = river_station.get(station.river, 0) + 1


    sorted_river_station = sorted(river_station.items(), key=lambda x: x[1], reverse = True)
    
 
    length = len(sorted_river_station)
    if N>= length: return sorted_river_station
    min_station_count = sorted_river_station[N-1][1]
    while N<length and  sorted_river_station[n] == min_station_count:
        N+=1
    return sorted_river_station[:N]

我要做的是,我找到第N条河流的站点计数,并从该河流迭代到最后,同时检查其余河流的站点数量是否相同

没有任何内置函数可以满足您的要求(据我所知),因此最好的方法似乎基本上就是您正在做的事情,按站点数量对河流进行分组,按站点数量进行排序,然后从排序列表中获取第一个N

我还将把代码分成两个独立的函数:一个函数接收站点列表并按河流名称收集它们,另一个函数接收这些(河流名称、站点计数)对,并提取第一个N

通过河流收集站点的功能

真正做到这一点的唯一方法是在所有的站点中循环并收集它们

from collections import Counter

def collect_stations( stations ):
    """
    :param stations: List of station objects.
    :returns: Dictionary like object of name-station count pairs.
    """
    river_count = {}
    names = [ s.river for s in stations ]
    return Counter( names )

返回第一个N站的函数

这是一个更紧凑的版本

def highest_counts( river_stations, N, flatten = True ):
    """
    :param river_stations: Dictionary like object of name-count pairs.
    :param N: Number of count groups to return.
    :param flatten: Flatten list of rivers.
    :returns: If flatten is True returns a list of ( name, count ) tuples of N unique counts. i.e. Rivers with the same number of counts are treated as one element. If flatten is False, a dictionary of { count: [ ( name, count ) ] is returned, with N count keys.
    """
    # group rivers by number of stations
    grouped = {}
    for name, count in river_stations.items():
        if count not in grouped:
            # add number group if it doesn't exist
            grouped[ count ] = []
            
        grouped[ count ].append( ( name, count ) )
        
    # sort groups by number of stations
    grouped = [ ( c, l ) for c, l in grouped.items() ]
    grouped.sort( key = lambda x: x[ 0 ], reverse = True )
    
    # get first N number groups
    stats = grouped[ :N ]

    if flatten:
        stats = [ 
            river 
            for num_list in stats
            for river in num_list[ 1 ]
        ]

    return stats

另一种方法是对初始列表进行排序,然后提取元素,直到看到N个站点编号

from collections import Counter

def highest_counts( river_stations, N ):
    """
    :param river_stations: Dictionary like object of name-count pairs.
    :param N: Number of count groups to return.
    :returns: List of ( name, count ) tuples of N unique counts. i.e. Rivers with the same number of counts are treated as one element.
    """
    # sorts by number of stations
    river_stations_list = [ ( name, count ) for name, count in river_stations.items() ]
    s = sorted( river_stations_list, key = lambda x: x[ 1 ], reverse = True )
    
    # gets number of stations for each element
    nums = [ x[ 1 ] for x in s ]
    
    # calculates how many indices incorporate first N number groups
    freqs = list( Counter( nums ).values() )
    ind = sum( freqs[ :N ] )
    
    # return first elements that incorporate N number groups
    return s[ :ind ]

进行快速性能检查后,第二个版本对于更大的输入速度更快。 Timing ratio of versions for differing input sizes.

最终功能

最后一个函数将结合上述两个函数

def rivers_by_station_number( stations, N ):
    """
    :param stations: List of station objects.
    :param N: Number of count groups to return.
    :returns: List of ( name, count ) tuples of N unique counts. i.e. Rivers with the same number of counts are treated as one element.
    """
    collected = collect_stations( stations ):
    return highest_counts( collected, N )

相关问题 更多 >