最小化和重新排列列表

麦可

我有一个列表,我想减少该列表中的值数量。因此,我订购了该列表并尝试使用范围,但是我有点卡住了。

到目前为止的代码:

ports=["1/1/1","1/1/3","2/1/5", "1/1/2", "2/1/6" ]
arange=[]
brange=[]
def test():
   for i in ports:
       num=i.split("/")
       portnum=num [-1]
       arange.append(portnum)
   portindex=i[:-1]
   arange.sort()
   for i in range(len(arange)-1):
       a, b= int (arange[i]), int (arange[i+1]) 
       if (a+1) == b:
           brange.append(portindex+arange[i]+"-"+str(b))
   print (brange)
test()

我的输出是:

['2/1/1-2', '2/1/2-3', '2/1/5-6']

我真正想要的是

['1/1/1-3','2/1/5-6']

有什么线索吗?

公路跑者

这是使用的解决方案collections.defaultdict它首先将端口分组为列表的默认值,然后使用minmax()实用程序功能输出分组的结果范围

from collections import defaultdict

ports = ["1/1/1", "1/1/3", "2/1/5", "1/1/2", "2/1/6"]

def minmax(numbers):
    """Returns minumum and maximum numbers in sequence"""
    return min(numbers), max(numbers)

# Group ports
d = defaultdict(list)
for port in ports:
    key, number = port.rsplit("/", 1)
    d[key].append(number)

print(["%s/%d-%d" % (k, *minmax(list(map(int, v)))) for k, v in d.items()])
# ['1/1/1-3', '2/1/5-6']

注意: str.rsplit()从右边分裂。特别是在这种情况下,1从右数第一个距离。

更新资料

如果要处理丢失的端口,可以尝试以下功能:

from collections import defaultdict
from operator import itemgetter
from itertools import groupby

def group_ports(ports):
    result = []

    # Group ports
    port_groups = defaultdict(list)
    for port in ports:
        key, number = port.rsplit("/", 1)
        port_groups[key].append(number)

    # Go through each port group
    for port, ranges in port_groups.items():

        # Sort ranges
        sorted_range = sorted(map(int, ranges))

        # Iterate grouped consecutive numbers 
        # e.g. [1,2,3,4,6,7] -> [[1,2,3,4], [6,7]]
        for _, g in groupby(enumerate(sorted_range), key=lambda x: x[0] - x[1]):
            # Get only numbers in sequence
            sequence = list(map(itemgetter(1), g))

            # Append port strings
            # Singleton sequences will be port/number, otherwise port/min-max
            result.append(
                "%s/%d" % (port, sequence[0])
                if len(sequence) == 1
                else "%s/%d-%d" % (port, sequence[0], sequence[-1])
            )

    return result

print(group_ports(["1/1/1", "1/1/3", "2/1/5", "1/1/2", "2/1/6"]))
print(group_ports(["1/1/1", "1/1/3", "1/1/2", "1/2/1", "1/2/3", "1/2/4"]))

输出:

['1/1/1-3', '2/1/5-6']
['1/1/1-3', '1/2/1', '1/2/3-4']

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章