Created
July 26, 2011 16:41
-
-
Save mitchellrj/1107194 to your computer and use it in GitHub Desktop.
Constrained list insertion in Python.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def constrained_insert(list_, item, before=None, after=None, strict=True): | |
""" Given a list and an item to be inserted into that list, attempts | |
to insert the item into the list in such a way that it is before | |
any items listed in the 'before' argument and after any of those | |
listed in the 'after' argument. If this is not possible, raises | |
a RuntimeError. | |
If any of the values in before or after do not appear in the | |
list, ValueError will be raised, unless 'strict' is set to | |
False. | |
""" | |
if before is not None and isinstance(before, basestring): | |
before = (before, ) | |
elif before is None: | |
before = () | |
if after is not None and isinstance(after, basestring): | |
after = (after, ) | |
elif after is None: | |
after = () | |
for i in before + after: | |
if i not in list_: | |
if strict: | |
raise ValueError('%s does not appear in the list' % (i,)) | |
else: | |
if i in before: | |
before.remove(i) | |
if i in after: | |
after.remove(i) | |
beforepos = min([len(list_)] + [list_.index(s) | |
for s in before | |
if s in list_]) | |
afterpos = max([0] + [list_.index(s) | |
for s in after | |
if s in list_]) + 1 | |
if before and after and afterpos > beforepos: | |
raise RuntimeError(('Unabled to resolve a position in %s to satisfy ' \ | |
'the constraints before: %s; after: %s.') % \ | |
(list_, before, after)) | |
if before and not after: | |
list_.insert(beforepos, item) | |
else: | |
# if we don't want it directly before something, insert it as | |
# early in the list as the 'after' constraint will allow. | |
list_.insert(afterpos, item) | |
return list_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment