Перестановка элементов в Python - PullRequest
0 голосов
/ 21 ноября 2018

Я новичок в Python и не могу этого получить. У меня есть Список, и я хочу взять оттуда входные данные и записать их в файлы.

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. Таким образом, любой Eth, имеющий 1 цифру перед "/" (например, Eth1 / 1 или Eth2 / 2), должен находиться в одном файле abc1.txt.

  2. Любой Eth, имеющий 3 цифры перед "/" (например, Eth101 / 1/1 или Eth 102/1/1), должен находиться в другом файле abc2.txt и. Поскольку они находятся в диапазонах, их нужно записать так:Eth101 / 1 / 1-3, Eth102 / 1 / 1-3 и т. Д.

Любая идея?

1 Ответ

0 голосов
/ 21 ноября 2018

Я не думаю, что вам здесь нужно регулярное выражение.Все ваши предметы начинаются с «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.

Так что это должно работать для вашего примера.Если вам действительно нужно регулярное выражение, это превратит вашу проблему в поиск хорошего регулярного выражения, отвечающего вашим потребностям, без каких-либо других проблем.

Поскольку эти значения находятся в диапазонах, необходимо написать их как Eth101 / 1 /1-3, Eth102 / 1 / 1-3 и т. Д.

Это то, чего вы можете достичь, сначала вычислив строку, а затем записав ее в файл.Но это больше похоже на отдельный вопрос.

ОБНОВЛЕНИЕ

Это не так просто вычислить правильные диапазоны сети.Здесь я могу представить вам один подход, который не меняет мой код, но добавляет некоторые функциональные возможности.Хитрость заключается в том, чтобы получить группы подключенных сетей, которые не прерываются их номерами.Для этого я скопировал 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')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...