如何在 python 中重新排列字符串行

How to re-arrange string lines in python

我有下面提到的字符串,每组包含 n 行,我想按照下面提到的方式排列字符串..

real   51.85ms
sys    22.41ms
usr    29.70ms
[www.ms786.com] 2345 sunset follow
Multidd    567890KB

real   61.85ms
sys    32.41ms
usr    27.70ms
[www.ms586.com] 4345 sunset follow
Multidd    4567890KB

real   51.85ms
sys    12.41ms
usr    41.70ms
[www.ms186.com] 7345 sunset follow
Multidd    8967890KB

[www.ms786.com] 2345 sunset follow
Multidd    567890KB
real   51.85ms
sys    22.41ms
usr    29.70ms
Multidd    567890KB

[www.ms586.com] 4345 sunset follow
Multidd    4567890KB
real   61.85ms
sys    32.41ms
usr    27.70ms

[www.ms186.com] 7345 sunset follow
Multidd    8967890KB
real   51.85ms
sys    12.41ms
usr    41.70ms`

你能帮忙看看如何在字符串本身中重新洗牌吗?非常感谢您的帮助

这个解决方案通过定位组 headers 并将它们移回正确的位置来有效地做到这一点:

s = """real   51.85ms
sys    22.41ms
usr    29.70ms
[www.ms786.com] 2345 sunset follow
Multidd    567890KB

real   61.85ms
sys    32.41ms
usr    27.70ms
[www.ms586.com] 4345 sunset follow
Multidd    4567890KB

real   51.85ms
sys    12.41ms
usr    41.70ms
[www.ms186.com] 7345 sunset follow
Multidd    8967890KB"""

def move_header_back(lines, header_prefix, base_index = 0):
    # Find group header positions
    group_header_positions = [base_index - 1] + [i + 1 for i in range(len(lines)) if lines[i].startswith(header_prefix)]
    # If no group positions found (there is one as we inserted `0` regardless)
    if 1 == len(group_header_positions):
        return lines
    # Shift back groups headers
    for i in range(1, len(group_header_positions)):
        group_header = lines.pop(group_header_positions[i] - 1)
        lines.insert(group_header_positions[i - 1] + 1, group_header)
    return lines

def fix_group_positions(lines):
    move_header_back(lines, header_prefix = '[',        base_index=0)
    move_header_back(lines, header_prefix = 'Multidd',  base_index=1)
    # Join back lines
    return '\n'.join(lines)

lines = [l for l in s.split('\n') if l]
print(fix_group_positions(lines))

输出:

[www.ms786.com] 2345 sunset follow
Multidd    567890KB
real   51.85ms
sys    22.41ms
usr    29.70ms
[www.ms586.com] 4345 sunset follow
Multidd    4567890KB
real   61.85ms
sys    32.41ms
usr    27.70ms
[www.ms186.com] 7345 sunset follow
Multidd    8967890KB
real   51.85ms
sys    12.41ms
usr    41.70ms

此代码通过定义每个块的行的排列方式来工作。例如 "340125" 旧的第 3 行将成为新的第 0 行,旧的第 4 行 -> 新的第 1 行,依此类推。
只要所有块的结构保持相同,它将适用于每个块最多 10 行的所有块结构。

class BlockRearrange:
    def __init__(self, order):
        self.order = list(map(int, order))
        self.blocksize = len(self.order)
    
    def reorder(self, s):
        result = ""
        lines = s.splitlines()

        for block_pos in range(0, len(lines), self.blocksize):
            part = lines[block_pos:block_pos+self.blocksize]
            part_length = len(part)

            for n in self.order:
                if n < part_length:
                    result += part[n] + "\n"
        
            if part_length < self.blocksize:
                break

        return result

# Create instance with formula for how to rearrange the blocks.
# The order-string needs to contain every line of the block,
# even those not changing positions.
br = BlockRearrange("340125")

print(br.reorder(s))