从python中的数字列表打印格式化的数字范围字符串

Bip*_*Bip 5 python

我写了这个类来压缩和扩展数字列表到序列字符串,包括步长值大于1时的步骤值.代码仍然感觉笨重.是否有可以执行此类操作的库?可能更简单的代码?

import re

class Foo( object ):

    def __init__( self, num_list ):
        self.num_list = sorted( list( set( [ int(n) for n in num_list ] ) ) )
    # end def __init__

    def gen_seq_data( self ):
        self.seq_data       = list()
        index_offset        = None
        backward_step_value = None
        forward_step_value  = None
        sub_list            = list()
        sub_list_step_value = None
        for index, num in enumerate( self.num_list ):

            if index - 1 < 0:
                backward_step_value = None
            # end if
            else:
                backward_step_value = num - self.num_list[ index - 1 ]
            # end else

            try:
                forward_step_value = self.num_list[ index + 1 ] - num
            # end try
            except IndexError:
                forward_step_value = None
            # end except

            if backward_step_value is None:
                sub_list.append( num )
            # end if
            elif backward_step_value == forward_step_value:
                sub_list.append( num )
                if forward_step_value is None:
                    self.seq_data.append( ( sub_list_step_value, sub_list ) )
                # end if
            # end if
            elif backward_step_value == sub_list_step_value:
                sub_list.append( num )
                if sub_list:
                    self.seq_data.append( ( sub_list_step_value, sub_list ) )
                # end if
                sub_list = list()
            # end elif
            else:
                if sub_list:
                    self.seq_data.append( ( sub_list_step_value, sub_list ) )
                # end if
                sub_list = [ num ]
                if forward_step_value is None:
                    self.seq_data.append( ( sub_list_step_value, sub_list ) )
                # end if
            # end else

            try:
                sub_list_step_value = sub_list[ -1 ] - sub_list[ -2 ]
            # end try
            except IndexError:
                sub_list_step_value = None
            # end except
        # end for
    # end def gen_seq_object

    def format_elements( self ):
        format_elements = list()
        for step, num_list in self.seq_data:
            if step is None:
                format_elements.append( '%s' % ( num_list[ 0 ] ) )
            # end if
            elif step == 1:
                format_elements.append( '%s-%s' % ( num_list[ 0 ], num_list[ -1 ] ) )
            # end elif
            else:
                format_elements.append( '%s-%sx%s' % ( num_list[ 0 ], num_list[ -1 ], step ) )
            # end else
        # end for
        return format_elements
    # end def format_range

    def format_range( self ):
       return ','.join( self.format_elements() )
    # end def format_range

    def expand_range( self ):
        num_list = list()
        for r_token in self.format_range().split( ',' ):
            if r_token.isdigit():
                num_list.append( int( r_token ) )
            # end if
            elif '-' in r_token:
                if 'x' in r_token:
                    start, end, step = re.split( r'[-|x]', r_token )
                    num_list.extend( range( int( start ), int( end ) + 1, int( step ) ) )
                # end if
                else:
                    start, end = r_token.split( '-' )
                    num_list.extend( range( int( start ), int( end ) + 1 ) )
                # end else
           # end elif
        # end for
        return num_list
    # end def expand_range

# end class Foo
Run Code Online (Sandbox Code Playgroud)

输入输出:

data = [ 1, 4, 5, 6, 10, 15, 16, 17, 18, 20, 22, 24, 26, 27, 28, 30, 35, 40, 45, 50, 56, 63, 66, 69, 72 ]

foo = Foo( data )
foo.gen_seq_data()

print data

print foo.format_range()
1,4-6,10,15-18,20-26x2,27,28,30-50x5,56,63-72x3

print foo.expand_range()
[1, 4, 5, 6, 10, 15, 16, 17, 18, 20, 22, 24, 26, 27, 28, 30, 35, 40, 45, 50, 56, 63, 66, 69, 72]
Run Code Online (Sandbox Code Playgroud)

S.L*_*ott 2

一。删除所有 #END 评论。它们毫无用处。你的缩进本身就说明了一切。用它。

二。别把这当成一堂课。它不是具有不同职责的不同对象。这只是一种算法。由函数组成。充其量它是一个具有所有静态方法的类。

三。永远不要这样做

    for index, num in enumerate( self.num_list ):
        if index - 1 < 0:
            backward_step_value = None
        # end if
        else:
            backward_step_value = num - self.num_list[ index - 1 ]
        # end else
Run Code Online (Sandbox Code Playgroud)

如果第一个元素特殊,则单独处理。

backward_step_value = self.num_list[0]
for num in self.num_list[1:]:
Run Code Online (Sandbox Code Playgroud)

像这样的事情很少需要索引。事实上,拥有索引的唯一原因似乎是特殊对待第一个元素。

最后,这是一个“减少”。使用生成器函数

def reduce_list( some_list ):
    v= min(some_list)
    low, high = v, v
    for v in sorted(some_list)[1:]:
        if v == high+1: 
            high= high+1
        else:
            yield low, high
     yield low, high
Run Code Online (Sandbox Code Playgroud)

这可能会产生您的连续范围列表。然后您可以格式化它们。

format_elements( reduce_list( some_list ) )
Run Code Online (Sandbox Code Playgroud)