use a regex or not?
Kent Johnson
kent37 at tds.net
Tue Jun 21 11:15:51 EDT 2005
Joost Jacob wrote:
> I am looking for a function that takes an input string
> and a pattern, and outputs a dictionary.
Here is one way. I won't say it's pretty but it is fairly straightforward and it passes all your tests.
Kent
def fill(s, p):
"""
>>> fill('ab', p='aA')
{'A': 'b'}
>>> fill('ab', p='Ab')
{'A': 'a'}
>>> fill('bb', p='Aa') # no match
{}
>>> fill('aa', p='Aa')
{'A': 'a'}
>>> fill('aa', p='Ab') # no match
{}
>>> fill('abb', p='aA')
{'A': 'bb'}
>>> fill('aba', p='aAa')
{'A': 'b'}
>>> fill('abb', p='aAa') # no match
{}
>>> fill('abab', p='aAaA') # A-matches must be equal
{'A': 'b'}
>>> fill('abac', p='aAaA') # no match
{}
>>> fill('abac', p='aAaB')
{'A': 'b', 'B': 'c'}
"""
# If s is longer than p the extra chars of s become part of the
# last item of s
if len(s) > len(p):
ss = list(s[:len(p)])
ss[-1] = ss[-1] + s[len(p):]
s = ss
d = {}
seen = {}
for s1, p1 in zip(s, p):
# Lower case have to map to themselves
if p1.islower() and s1 != p1:
# print 'Non-identity map for %s: %s' % (p1, s1)
return {}
try:
# Check for multiple mappings from p1
old_s = d[p1]
if old_s != s1:
# We saw this s before but the mapping is different
return {}
# We saw this s1, p1 before with the same mapping
continue
except KeyError:
# Check for multiple mappings to p1
if seen.get(s1, p1.lower()) != p1.lower():
return {}
# This is a new mapping
d[p1] = s1
seen[s1] = p1.lower()
# Strip out the lower case mappings
return dict((k, v) for k, v in d.iteritems() if k.isupper())
def _test():
import doctest
doctest.testmod()
if __name__ == "__main__":
_test()
More information about the Python-list
mailing list