From: Sneaky Wombat on
[ {'vlan_or_intf': 'VLAN2021'},
{'vlan_or_intf': 'Interface'},
{'vlan_or_intf': 'Po1'},
{'vlan_or_intf': 'Po306'},
{'vlan_or_intf': 'VLAN2022'},
{'vlan_or_intf': 'Interface'},
{'vlan_or_intf': 'Gi7/33'},
{'vlan_or_intf': 'Po1'},
{'vlan_or_intf': 'Po306'},
{'vlan_or_intf': 'VLAN2051'},
{'vlan_or_intf': 'Interface'},
{'vlan_or_intf': 'Gi9/6'},
{'vlan_or_intf': 'VLAN2052'},
{'vlan_or_intf': 'Interface'},
{'vlan_or_intf': 'Gi9/6'},]

I want it to be converted to:

[{'2021':['Po1','Po306']},{'2022':['Gi7/33','Po1','Po306']},etc etc]

I was going to write a def to loop through and look for certain pre-
compiled regexs, and then put them in a new dictionary and append to a
list, but I'm having trouble thinking of a good way to capture each
dictionary. Each dictionary will have a key that is the vlan and the
value will be a list of interfaces that participate in that vlan.
Each list will be variable, many containing only one interface and
some containing many interfaces.

I thought about using itertools, but i only use that for fixed data.
I don't know of a good way to loop over variably sized data. I was
wondering if anyone had any ideas about a good way to convert this
list or dictionary into the right format that I need. The solution I
come up with will most likely be ugly and error prone, so I thought
i'd ask this python list while I work. Hopefully I learn a better way
to solve this problem.

Thanks!

I also have the data in a list,

[ 'VLAN4065',
'Interface',
'Gi9/6',
'Po2',
'Po3',
'Po306',
'VLAN4068',
'Interface',
'Gi9/6',
'VLAN4069',
'Interface',
'Gi9/6',]
From: mk on
Sneaky Wombat wrote:
> I was going to write a def to loop through and look for certain pre-
> compiled regexs, and then put them in a new dictionary and append to a
> list,

regexes are overkill in this case I think.

> [ 'VLAN4065',
> 'Interface',
> 'Gi9/6',
> 'Po2',
> 'Po3',
> 'Po306',
> 'VLAN4068',
> 'Interface',
> 'Gi9/6',
> 'VLAN4069',
> 'Interface',
> 'Gi9/6',]

Why not construct an intermediate dictionary?

elems = [ 'VLAN4065',
'Interface',
'Gi9/6',
'Po2',
'Po3',
'Po306',
'VLAN4068',
'Interface',
'Gi9/6',
'VLAN4069',
'Interface',
'Gi9/6',]

def makeintermdict(elems):
vd = {}
vlan = None
for el in elems:
if el.startswith('VLAN'):
vlan = el.replace('VLAN','')
elif el == 'Interface':
vd[vlan] = []
else:
vd[vlan].append(el)
return vd

def makelist(interm):
finlist = []
for k in interm.keys():
finlist.append({k:interm[k]})
return finlist

if __name__ == "__main__":
intermediate = makeintermdict(elems)
print intermediate
finlist = makelist(intermediate)
print 'final', finlist


{'4068': ['Gi9/6'], '4069': ['Gi9/6'], '4065': ['Gi9/6', 'Po2', 'Po3',
'Po306']}
final [{'4068': ['Gi9/6']}, {'4069': ['Gi9/6']}, {'4065': ['Gi9/6',
'Po2', 'Po3', 'Po306']}]

I hope this is not your homework. :-)

Regards,
mk

From: Sneaky Wombat on
On Mar 4, 10:55 am, mk <mrk...(a)gmail.com> wrote:
> Sneaky Wombat wrote:
> > I was going to write a def to loop through and look for certain pre-
> > compiled regexs, and then put them in a new dictionary and append to a
> > list,
>
> regexes are overkill in this case I think.
>
> > [ 'VLAN4065',
> >  'Interface',
> >  'Gi9/6',
> >  'Po2',
> >  'Po3',
> >  'Po306',
> >  'VLAN4068',
> >  'Interface',
> >  'Gi9/6',
> >  'VLAN4069',
> >  'Interface',
> >  'Gi9/6',]
>
> Why not construct an intermediate dictionary?
>
> elems = [ 'VLAN4065',
>   'Interface',
>   'Gi9/6',
>   'Po2',
>   'Po3',
>   'Po306',
>   'VLAN4068',
>   'Interface',
>   'Gi9/6',
>   'VLAN4069',
>   'Interface',
>   'Gi9/6',]
>
> def makeintermdict(elems):
>      vd = {}
>      vlan = None
>      for el in elems:
>          if el.startswith('VLAN'):
>              vlan = el.replace('VLAN','')
>          elif el == 'Interface':
>              vd[vlan] = []
>          else:
>              vd[vlan].append(el)
>      return vd
>
> def makelist(interm):
>      finlist = []
>      for k in interm.keys():
>          finlist.append({k:interm[k]})
>      return finlist
>
> if __name__ == "__main__":
>      intermediate = makeintermdict(elems)
>      print intermediate
>      finlist = makelist(intermediate)
>      print 'final', finlist
>
> {'4068': ['Gi9/6'], '4069': ['Gi9/6'], '4065': ['Gi9/6', 'Po2', 'Po3',
> 'Po306']}
> final [{'4068': ['Gi9/6']}, {'4069': ['Gi9/6']}, {'4065': ['Gi9/6',
> 'Po2', 'Po3', 'Po306']}]
>
> I hope this is not your homework. :-)
>
> Regards,
> mk

Thanks mk,

My approach was a lot more complex than yours, but your's is better.
I like itertools and was using islice to create tuples for (start,end)
string slicing. Too much work though. Thanks!

-j
From: lbolla on
On Mar 4, 3:57 pm, Sneaky Wombat <joe.hr...(a)gmail.com> wrote:
> [ {'vlan_or_intf': 'VLAN2021'},
>  {'vlan_or_intf': 'Interface'},
>  {'vlan_or_intf': 'Po1'},
>  {'vlan_or_intf': 'Po306'},
>  {'vlan_or_intf': 'VLAN2022'},
>  {'vlan_or_intf': 'Interface'},
>  {'vlan_or_intf': 'Gi7/33'},
>  {'vlan_or_intf': 'Po1'},
>  {'vlan_or_intf': 'Po306'},
>  {'vlan_or_intf': 'VLAN2051'},
>  {'vlan_or_intf': 'Interface'},
>  {'vlan_or_intf': 'Gi9/6'},
>  {'vlan_or_intf': 'VLAN2052'},
>  {'vlan_or_intf': 'Interface'},
>  {'vlan_or_intf': 'Gi9/6'},]
>
> I want it to be converted to:
>
> [{'2021':['Po1','Po306']},{'2022':['Gi7/33','Po1','Po306']},etc etc]
>
> I was going to write a def to loop through and look for certain pre-
> compiled regexs, and then put them in a new dictionary and append to a
> list, but I'm having trouble thinking of a good way to capture each
> dictionary.  Each dictionary will have a key that is the vlan and the
> value will be a list of interfaces that participate in that vlan.
> Each list will be variable, many containing only one interface and
> some containing many interfaces.
>
> I thought about using itertools, but i only use that for fixed data.
> I don't know of a good way to loop over variably sized data.  I was
> wondering if anyone had any ideas about a good way to convert this
> list or dictionary into the right format that I need.  The solution I
> come up with will most likely be ugly and error prone, so I thought
> i'd ask this python list while I work.  Hopefully I learn a better way
> to solve this problem.
>
> Thanks!
>
> I also have the data in a list,
>
> [ 'VLAN4065',
>  'Interface',
>  'Gi9/6',
>  'Po2',
>  'Po3',
>  'Po306',
>  'VLAN4068',
>  'Interface',
>  'Gi9/6',
>  'VLAN4069',
>  'Interface',
>  'Gi9/6',]



===================================

from itertools import groupby

data = \
[ {'vlan_or_intf': 'VLAN2021'},
{'vlan_or_intf': 'Interface'},
{'vlan_or_intf': 'Po1'},
{'vlan_or_intf': 'Po306'},
{'vlan_or_intf': 'VLAN2022'},
{'vlan_or_intf': 'Interface'},
{'vlan_or_intf': 'Gi7/33'},
{'vlan_or_intf': 'Po1'},
{'vlan_or_intf': 'Po306'},
{'vlan_or_intf': 'VLAN2051'},
{'vlan_or_intf': 'Interface'},
{'vlan_or_intf': 'Gi9/6'},
{'vlan_or_intf': 'VLAN2052'},
{'vlan_or_intf': 'Interface'},
{'vlan_or_intf': 'Gi9/6'},]

def clean_up(lst):
return [d.values()[0] for d in data if d.values()[0] != 'Interface']

out = {}
for k, g in groupby(clean_up(data) , key=lambda s:
s.startswith('VLAN')):
if k:
key = list(g)[0].replace('VLAN','')
else:
out[key] = list(g)

print out
===================================

hth,
L.
From: nn on


lbolla wrote:
> On Mar 4, 3:57 pm, Sneaky Wombat <joe.hr...(a)gmail.com> wrote:
> > [ {'vlan_or_intf': 'VLAN2021'},
> >  {'vlan_or_intf': 'Interface'},
> >  {'vlan_or_intf': 'Po1'},
> >  {'vlan_or_intf': 'Po306'},
> >  {'vlan_or_intf': 'VLAN2022'},
> >  {'vlan_or_intf': 'Interface'},
> >  {'vlan_or_intf': 'Gi7/33'},
> >  {'vlan_or_intf': 'Po1'},
> >  {'vlan_or_intf': 'Po306'},
> >  {'vlan_or_intf': 'VLAN2051'},
> >  {'vlan_or_intf': 'Interface'},
> >  {'vlan_or_intf': 'Gi9/6'},
> >  {'vlan_or_intf': 'VLAN2052'},
> >  {'vlan_or_intf': 'Interface'},
> >  {'vlan_or_intf': 'Gi9/6'},]
> >
> > I want it to be converted to:
> >
> > [{'2021':['Po1','Po306']},{'2022':['Gi7/33','Po1','Po306']},etc etc]
> >
> > I was going to write a def to loop through and look for certain pre-
> > compiled regexs, and then put them in a new dictionary and append to a
> > list, but I'm having trouble thinking of a good way to capture each
> > dictionary.  Each dictionary will have a key that is the vlan and the
> > value will be a list of interfaces that participate in that vlan.
> > Each list will be variable, many containing only one interface and
> > some containing many interfaces.
> >
> > I thought about using itertools, but i only use that for fixed data.
> > I don't know of a good way to loop over variably sized data.  I was
> > wondering if anyone had any ideas about a good way to convert this
> > list or dictionary into the right format that I need.  The solution I
> > come up with will most likely be ugly and error prone, so I thought
> > i'd ask this python list while I work.  Hopefully I learn a better way
> > to solve this problem.
> >
> > Thanks!
> >
> > I also have the data in a list,
> >
> > [ 'VLAN4065',
> >  'Interface',
> >  'Gi9/6',
> >  'Po2',
> >  'Po3',
> >  'Po306',
> >  'VLAN4068',
> >  'Interface',
> >  'Gi9/6',
> >  'VLAN4069',
> >  'Interface',
> >  'Gi9/6',]
>
>
>
> ===================================
>
> from itertools import groupby
>
> data = \
> [ {'vlan_or_intf': 'VLAN2021'},
> {'vlan_or_intf': 'Interface'},
> {'vlan_or_intf': 'Po1'},
> {'vlan_or_intf': 'Po306'},
> {'vlan_or_intf': 'VLAN2022'},
> {'vlan_or_intf': 'Interface'},
> {'vlan_or_intf': 'Gi7/33'},
> {'vlan_or_intf': 'Po1'},
> {'vlan_or_intf': 'Po306'},
> {'vlan_or_intf': 'VLAN2051'},
> {'vlan_or_intf': 'Interface'},
> {'vlan_or_intf': 'Gi9/6'},
> {'vlan_or_intf': 'VLAN2052'},
> {'vlan_or_intf': 'Interface'},
> {'vlan_or_intf': 'Gi9/6'},]
>
> def clean_up(lst):
> return [d.values()[0] for d in data if d.values()[0] != 'Interface']
>
> out = {}
> for k, g in groupby(clean_up(data) , key=lambda s:
> s.startswith('VLAN')):
> if k:
> key = list(g)[0].replace('VLAN','')
> else:
> out[key] = list(g)
>
> print out
> ===================================
>
> hth,
> L.

Good use of groupby. Here is what I ended up coming up:

from itertools import groupby
laninfo=[ 'VLAN4065',
'Interface',
'Gi9/6',
'Po2',
'Po3',
'Po306',
'VLAN4068',
'Interface',
'Gi9/6',
'VLAN4069',
'Interface',
'Gi9/6',]

def splitgrp(s, f=[False]):
f[0]^=s.startswith('VLAN')
return f[0]
lanlst=(list(g) for k,g in groupby(laninfo,key=splitgrp))
out={item[0][4:]:item[2:] for item in lanlst}
print(out)