Задача: написать этот код идиоматически.
Суть проблемы: формат такой: строка, начинающаяся не с пробела - начало записи. Дальше сколько-то строк, начинающихся с пробелов, относящихся к этой же самой записи.
Т.е.
foo foobar
bar
bar
next foobar
bar
etc
Задача - распарсить на записи, так, чтобы каждая "запись" была массивом "своих" строк (
(
Read more... )
Comments 32
Reply
Reply
Reply
https://github.com/amarao/ansible/blob/8eea26b207b5a01c725efc1acce942de0c137c39/lib/ansible/modules/net_tools/ip_link_set.py
Reply
Reply
Reply
In [2]: text= '''foo foobar
bar
bar
next foobar
bar
bar
etc
'''
Out[2]:
In [4]: [(block[0], block[1:]) for block in [fragment.splitlines() for fragment in re.split('\n(?=\w)', text)]]
Out[4]:
[('foo foobar', [' bar', ' bar']),
('next foobar', [' bar', ' bar']),
('etc', [])]
(код для иллюстрации)
Reply
In [16]: import json ( ... )
Reply
iterable = (line for line in raw_output.split(‘\n’) if line)
def children():
for child in iterable:
if child[0] != ‘ ‘:
children.parent = child
return
yield child
children.parent = None
children.parent = next(iterable, None)
while children.parent is not None:
yield children.parent, children()
Reply
Reply
Reply
Reply
from itertools import groupby
iterable = (line for line in raw_input.split('\n') if line)
def key_func(line):
if line[0] != ' ':
key_func.state = not key_func.state
return key_func.state
key_func.state = True
result = (group for _, group in groupby(iterable, key=key_func))
семантика, кстати, ближе к вашему первоначальному коду.
Reply
Вот вариация на массивах
>>> test="""foo foobar
... bar
... bar
... next bar
... bar
... end"""
>>> def join(acc, line): return (acc[-1].append(line) if line.startswith(' ') else acc.append([line])) or acc
...
>>> import functools
>>> functools.reduce(join, test.split('\n'), [])
[['foo foobar', ' bar', ' bar'], ['next bar', ' bar'], ['end']]
Reply
or acc мой мозг возмутился. Понятно, но всё равно WTF. Не питонически.
Reply
Leave a comment