pattern to dictionary of lists Python

2019-09-05 21:29发布

I have a file like this

module1 instance1(.wire1 (connectionwire1), .wire2 (connectionwire2),.... ,wire100 (connectionwire100)) ; module 2 instance 2(.wire1 (newconnectionwire1), .wire2 (newconnectionwire2),.... ,wire99 (newconnectionwire99)) 

Ther wires are repeated along modules. There can be many modules. I want to build a dictionary like this (not every wire in 2nd module is a duplicate).

[wire1:[(module1, instance1, connection1), (module2, instance2,newconnection1), wire2:[(module1 instance1 connection2),(module2, instance2,newconnection1)]... wire99:module2, instance2, connection99), ]

I am splitting the string on ; then splitting on , and then ( to get wire and connectionwire strings . I am not sure how to fill the data structure though so the wire is the key and module, instancename and connection are elements.

Goal- get this datastructure- [ wire: (module, instance, connectionwire) ] 

filedata=file.read()
realindex=list(find_pos(filedata,';'))
tempindex=0
for l in realindex:
    module=filedata[tempindex:l]
    modulename=module.split()[0]
    openbracketindex=module.find("(")
    closebracketindex=module.strip("\n").find(");")
    instancename=module[:openbracketindex].split()[1]
    tempindex=l
    tempwires=module[openbracketindex:l+1]
    #got to split wires on commas
    for tempw in tempwires.split(","):
        wires=tempw
        listofwires.append(wires)

标签: python
2条回答
\"骚年 ilove
2楼-- · 2019-09-05 22:05

Answer provided by wwii using re is correct. I'm sharing an example of how you can solve your problem using pyparsing module which makes parsing human readable and easy to do.

from pyparsing import Word, alphanums, Optional, ZeroOrMore, Literal, Group, OneOrMore
from collections import defaultdict
s = 'module1 instance1(.wire1 (connectionwire1), .wire2 (connectionwire2), .wire100 (connectionwire100)) ; module2 instance2(.wire1 (newconnectionwire1), .wire2 (newconnectionwire  2), .wire99 (newconnectionwire99))'
connection = Word(alphanums)
wire = Word(alphanums)
module = Word(alphanums)
instance = Word(alphanums)
dot = Literal(".").suppress()
comma = Literal(",").suppress()
lparen = Literal("(").suppress()
rparen = Literal(")").suppress()
semicolon = Literal(";").suppress()
wire_connection = Group(dot + wire("wire") + lparen + connection("connection") + rparen + Optional(comma))
wire_connections = Group(OneOrMore(wire_connection))
module_instance = Group(module("module") + instance("instance") + lparen + ZeroOrMore(wire_connections("wire_connections")) + rparen + Optional(semicolon))
module_instances = OneOrMore(module_instance)
results = module_instances.parseString(s)
# create a dict
d = defaultdict(list)
for r in results:
    m = r['module']
    i = r['instance']
    for wc in r['wire_connections']:
        w = wc['wire']
        c = wc['connection']
        d[w].append((m, i, c)) 
print d

Output:

defaultdict(<type 'list'>, {'wire1': [('module1', 'instance1', 'connectionwire1'), ('module2', 'instance2', 'newconnectionwire1')], 'wire2': [('module1', 'instance1', 'connectionwire2'), ('module2', 'instance2', 'newconnectionwire2')], 'wire100': [('module1', 'instance1', 'connectionwire100')], 'wire99': [('module2', 'instance2', 'newconnectionwire99')]})
查看更多
Evening l夕情丶
3楼-- · 2019-09-05 22:08

Using the re module.

import re
from collections import defaultdict

s = "module1 instance1(.wire1 (connectionwire1), .wire2 (connectionwire2), .wire100 (connectionwire100)) ; module2 instance2(.wire1 (newconnectionwire1), .wire2 (newconnectionwire2), wire99 (newconnectionwire99))'

d = defaultdict(list)
module_pattern = r'(\w+)\s(\w+)\(([^;]+)'
mod_rex = re.compile(module_pattern)
wire_pattern = r'\.(\w+)\s\(([^\)]+)'
wire_rex = re.compile(wire_pattern)

for match in mod_rex.finditer(s):
    #print '\n'.join(match.groups())
    module, instance, wires = match.groups()
    for match in wire_rex.finditer(wires):
        wire, connection = match.groups()
        #print '\t', wire, connection
        d[wire].append((module, instance, connection))

for k, v in d.items():
    print k, ':', v

Produces

wire1 : [('module1', 'instance1', 'connectionwire1'), ('module2', 'instance2', 'newconnectionwire1')]
wire2 : [('module1', 'instance1', 'connectionwire2'), ('module2', 'instance2', 'newconnectionwire2')]
wire100 : [('module1', 'instance1', 'connectionwire100')]   
查看更多
登录 后发表回答