remove dotted keys, a terrible idea

This commit is contained in:
James Turk 2010-02-19 23:10:50 -05:00
parent 2cde3badad
commit 293c7a0a78
2 changed files with 4 additions and 100 deletions

View File

@ -236,8 +236,7 @@ class FieldCopier(Filter):
def process_record(self, record):
# mapping is dest:source
for dest, source in self._copy_mapping.iteritems():
srcval = utils.dotted_key_lookup(record, source)
utils.dotted_key_set(record, dest, srcval)
record[dest] = record[source]
return record
class FieldRenamer(Filter):
@ -254,12 +253,11 @@ class FieldRenamer(Filter):
# mapping is dest:source
for dest, source in self._rename_mapping.iteritems():
try:
srcval = utils.dotted_key_pop(record, source)
utils.dotted_key_set(record, dest, srcval)
record[dest] = record.pop(source)
except KeyError:
# silently pass if source key didn't exist
pass
return record
return record
class Splitter(Filter):
""" Filter that splits nested data into different paths.

View File

@ -67,100 +67,6 @@ def str_or_list(obj):
else:
return obj
def dotted_key_lookup(dict_, dotted_key, default=KeyError, separator='.'):
"""
Do a lookup within dict_ by the various elements of dotted_key.
Optionally specify a default to return if key does not exist (similar
to default)
>>> d = {'a': {'b': {'c': 3} } }
>>> dotted_key_lookup(d, 'a.b.c')
3
>>> dotted_key_lookup(d, 'a.z', -1)
-1
>>> dotted_key_lookup(d, 'a|b|c', separator='|')
3
"""
val = dict_
try:
for key in dotted_key.split(separator):
if isinstance(val, dict):
val = val[key]
elif isinstance(val, (list,tuple)):
val = val[int(key)]
else:
val = getattr(val, key)
except (KeyError, IndexError, AttributeError):
if default is KeyError:
raise
val = default
return val
def dotted_key_pop(dict_, dotted_key, default=KeyError, separator='.'):
"""
Delete a value within dict_ by the various elements of dotted_key.
"""
val = dict_
try:
key_parts = dotted_key.split(separator)
for key in key_parts[:-1]:
if isinstance(val, dict):
val = val[key]
elif isinstance(val, (list,tuple)):
val = val[int(key)]
else:
val = getattr(val, key)
# now with just the final part of the key
key = key_parts[-1]
if isinstance(val, dict):
retval = val[key]
del val[key]
elif isinstance(val, (list,tuple)):
retval = val[int(key)]
del val[int(key)]
else:
retval = getattr(val, key)
delattr(val, key)
except (KeyError, IndexError, AttributeError):
if default is KeyError:
raise
retval = default
return retval
def dotted_key_set(dict_or_list, dotted_key, value, separator='.'):
"""
Set a value within dict_ using a dotted_key.
>>> d = {}
>>> dotted_key_set(d, 'a.b.c', 123}
>>> d
{'a': {'b': {'c': 123}}}
"""
# split key into composite parts
keys = dotted_key.split(separator)
for i,key in enumerate(keys):
# if current location is a dictionary: traverse inward until @ last key
# set value when last key is reached
if isinstance(dict_or_list, dict):
if i == len(keys)-1:
dict_or_list[key] = value
else:
try:
dict_or_list = dict_or_list[key]
except KeyError:
break
# if current location is a list: call dotted_key_set on each element
elif isinstance(dict_or_list, (tuple, list)):
newkey = separator.join(keys[i:])
for item in dict_or_list:
dotted_key_set(item, newkey, value, separator)
#
# utility classes
#
@ -188,4 +94,4 @@ class Files(object):
f = open(path)
for line in f:
yield line
f.close()
f.close()