Список к кортежам в Python - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть список в Python, например:

test = ['Vlan101', '1.1.1.0/24', 'Vlan111', '2.1.1.0/24', 'Vlan701', '3.1.1.0/24', 'Vlan703', '4.1.1.0/24', '5.5.5.0/24']

Я бы хотел, чтобы из него создавались кортежи, как показано ниже:

Vlan101,1.1.1.0/24
Vlan111,2.1.1.0/24
Vlan701,3.1.1.0/24
Vlan703,4.1.1.0/24, 5.5.5.0/24

Важно то, чтопоследний, который имеет 2 значения для одного и того же ключа.Это было хедшкратом для меня.

Ответы [ 3 ]

0 голосов
/ 05 декабря 2018

Вы можете использовать itertools.groupby() + zip() здесь:

from itertools import groupby

test = [
    "Vlan101",
    "1.1.1.0/24",
    "Vlan111",
    "2.1.1.0/24",
    "Vlan701",
    "3.1.1.0/24",
    "Vlan703",
    "4.1.1.0/24",
    "5.5.5.0/24",
]

print(
    [
        (x,) + y
        for x, y in zip(
            (x_ for x_ in test if x_.startswith("Vlan")),
            (
                tuple(g)
                for k, g in groupby(test, key=lambda x__: x__.startswith("Vlan"))
                if not k
            ),
        )
    ] 
)

# [('Vlan101', '1.1.1.0/24'), ('Vlan111', '2.1.1.0/24'), ('Vlan701', '3.1.1.0/24'), ('Vlan703', '4.1.1.0/24', '5.5.5.0/24')]
0 голосов
/ 05 декабря 2018

Второй, третий и т. Д. Элементы ваших кортежей выглядят как ip-адреса.Вы можете использовать регулярные выражения для распознавания определенного формата. (я рискну предположить, что вы будете играть с ip-адресами) .

Вот еще одно решение, менее чистое, чем у Рафаэля или RoadRunner's , но допускает произвольное количество адресов.

import re

test = [
        'Vlan101',
        '1.1.1.0/24',
        'Vlan111',
        '2.1.1.0/24',
        'Vlan701', 
        '3.1.1.0/24', 
        'Vlan703', 
        '4.1.1.0/24', 
        '5.5.5.0/24']

result = [[]]  # we first store the stuff as lists to allow for appending
for item in test:

    # matches ipaddresses with xxx.xxx.xxx.xxx/xx
    if re.match(r'\d{,3}\.\d{,3}\.\d{,3}\.\d{,3}/\d+', item):
        result[-1].append(item)    # appends an ipaddress
    else:
        result.append([item])      # appends a new 'Vlan...' (i.e. anything but an ipaddress)

tups = list(map(tuple, result))    # cast each of the lists into tuples

print(result)
print(tups)

Вывод:

[[], ['Vlan101', '1.1.1.0/24'], ['Vlan111', '2.1.1.0/24'], ['Vlan701', '3.1.1.0/24'], ['Vlan703', '4.1.1.0/24', '5.5.5.0/24']]
[(), ('Vlan101', '1.1.1.0/24'), ('Vlan111', '2.1.1.0/24'), ('Vlan701', '3.1.1.0/24'), ('Vlan703', '4.1.1.0/24', '5.5.5.0/24')]

Пустые [] и () находятся в началеЕсли ваш список test начинается сразу с адресов (это обеспечивает запасной вариант для result[-1]).

Если вы хотите удалить эти результаты, просто сделайте срез

print(tups[1:])

Вывод:

[('Vlan101', '1.1.1.0/24'), ('Vlan111', '2.1.1.0/24'), ('Vlan701', '3.1.1.0/24'), ('Vlan703', '4.1.1.0/24', '5.5.5.0/24')]
0 голосов
/ 05 декабря 2018

Можно использовать zip + iter для обобщенного способа сделать это

i = len(test)%2
s = iter(test[:-(2+i)])
[x for x in zip(s,s)] + [tuple(test[-(2+i):])]

Выходы

[('Vlan101', '1.1.1.0/24'),
 ('Vlan111', '2.1.1.0/24'),
 ('Vlan701', '3.1.1.0/24'),
 ('Vlan703', '4.1.1.0/24', '5.5.5.0/24')]

Если вы хотите, чтобы внешний объект также был tuple

tuple(x for x in zip(s,s)) + (tuple(test[-(2+i):]),)

(('Vlan101', '1.1.1.0/24'),
 ('Vlan111', '2.1.1.0/24'),
 ('Vlan701', '3.1.1.0/24'),
 ('Vlan703', '4.1.1.0/24', '5.5.5.0/24'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...