重新排列 Python 中的元素

Rearranging elements in Python

我是 Python 的新手,我无法获得 this.I 有一个列表,我想从那里获取输入并将其写入文件。

p = ['Eth1/1', 'Eth1/5','Eth2/1', 'Eth2/4','Eth101/1/1', 'Eth101/1/2', 'Eth101/1/3','Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3','Eth103/1/1', 'Eth103/1/2', 'Eth103/1/3','Eth103/1/4','Eth104/1/1', 'Eth104/1/2', 'Eth104/1/3','Eth104/1/4']

我正在尝试什么:

with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
for i in p:
    if len(i.partition("/")[0]) == 4:
        fw1.write('int ' + i + '\n  mode\n')
    else:
        i = 0
        while i < len(p):
            start = p[i].split('/')
            if (start[0] == 'Eth101'):
                i += 3

            key = start[0]
            i += 1
            while i < len(p) and p[i].split('/')[0] == key:
                i += 1
            end = p[i-1].split('/')
            fw2.write('confi ' + start[0] + '/' + start[1] + '-' + end[1] + '\n mode\n')

我在找什么:

abc1.txt 应该有

int Eth1/1
  mode
int Eth1/5
  mode
int Eth2/1
  mode
int Eth 2/4
  mode

abc2.txt 应该有:

int Eth101/1/1-3
  mode
int Eth102/1/1-3
  mode
int Eth103/1/1-4
  mode
int Eth104/1/1-4
  mode
  1. So any Eth having 1 digit before " / " ( e:g Eth1/1 or Eth2/2 )should be in one file that is abc1.txt .

  2. Any Eth having 3 digit before " / " ( e:g Eth101/1/1 or Eth 102/1/1 ) should be in another file that is abc2.txt and .As these are in ranges , need to write it like Eth101/1/1-3, Eth102/1/1-3 etc

有什么想法吗?

我认为您在这里根本不需要正则表达式。您的所有项目都以 'Eth' 开头,后跟一位或多位数字。因此,您可以在第一个 / 发生之前检查项目的长度,然后将其写入文件。

p = ['Eth1/1', 'Eth1/5','Eth2/1', 'Eth2/4','Eth101/1/1', 'Eth101/1/2', 'Eth101/1/3','Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3','Eth103/1/1', 'Eth103/1/2', 'Eth103/1/3','Eth103/1/4','Eth104/1/1', 'Eth104/1/2', 'Eth104/1/3','Eth104/1/4']

with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
    for i in p:
        if len(i.partition("/")[0]) == 4:
            fw1.write('int ' + i + '\n  mode\n')
        else:
            fw2.write('int ' + i + '\n  mode\n')

我稍微重构了您的代码以使 with-语句发挥作用。这将在最后正确处理关闭文件。也没有必要在序列上迭代两次,所以一次迭代就完成了。

如果数据不如提供的那么干净,那么您可能需要使用正则表达式。独立于正则表达式本身,通过编写 if re.match(r'((Eth\d{1}\/\d{1,2})', "p" ) 可以证明是否可以为字符串 "p" 上的给定正则表达式创建匹配对象,而不是变量 p 的值。这是因为您在 p 周围使用了 "

所以这应该适用于您的示例。如果你真的需要一个正则表达式,这将解决你的问题,找到一个好的正则表达式来满足你的需求而没有任何其他问题。

As these are in ranges , need to write it like Eth101/1/1-3, Eth102/1/1-3 etc

这可以通过先计算字符串然后将其写入文件来实现。但这更像是一个单独的问题。

更新

计算正确的网络范围并非易事。在这里,我可以向您介绍一种方法,它不会更改我的代码但会添加一些功能。这里的技巧是获取不被其数量打断的连接网络组。为此,我复制了 consecutive_groups。您当然也可以执行 pip install more-itertools 以获得该功能。而且我还将列表转换为字典以准备魔法,然后将字典重新转换为列表。肯定有更好的方法,但这至少适用于您的输入数据。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from itertools import groupby
from operator import itemgetter

p = ['Eth1/1', 'Eth1/5', 'Eth2/1', 'Eth2/4', 'Eth101/1/1', 'Eth101/1/2',
     'Eth101/1/3', 'Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3', 'Eth103/1/1',
     'Eth103/1/2', 'Eth103/1/3', 'Eth103/1/4', 'Eth104/1/1', 'Eth104/1/2',
     'Eth104/1/3', 'Eth104/1/4']


def get_network_ranges(networks):
    network_ranges = {}
    result = []

    for network in networks:
        parts = network.rpartition("/")
        network_ranges.setdefault(parts[0], []).append(int(parts[2]))

    for network, ranges in network_ranges.items():
        ranges.sort()
        for group in consecutive_groups(ranges):
            group = list(group)
            if len(group) == 1:
                result.append(network + "/" + str(group[0]))
            else:
                result.append(network + "/" + str(group[0]) + "-" +
                              str(group[-1]))

    result.sort()  # to get ordered results
    return result


def consecutive_groups(iterable, ordering=lambda x: x):
    """taken from more-itertools (latest)"""
    for k, g in groupby(
        enumerate(iterable), key=lambda x: x[0] - ordering(x[1])
    ):
        yield map(itemgetter(1), g)


# only one line added to do the magic
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
    p = get_network_ranges(p)
    for i in p:
        if len(i.partition("/")[0]) == 4:
            fw1.write('int ' + i + '\n  mode\n')
        else:
            fw2.write('int ' + i + '\n  mode\n')