Skip to content

Instantly share code, notes, and snippets.

@laginha
Last active December 8, 2019 10:28
Show Gist options
  • Save laginha/0a2e6c726048fe07d8fc19f44d184613 to your computer and use it in GitHub Desktop.
Save laginha/0a2e6c726048fe07d8fc19f44d184613 to your computer and use it in GitHub Desktop.
Convert lists and dictionaries to type instances, for js-like objects and ruby-like lists
from operator import getitem
from functools import reduce
def getindex(array, index, default=None):
'''
getindex(['foo', 'bar'], 1) => 'bar'
getindex(['foo', 'bar'], 2) => None
'''
try:
return array[index]
except IndexError:
return default
def first(array, default=None):
'''
first(['foo', 'bar']) => 'foo'
'''
return getindex(array, 0, default)
def last(array, default=None):
'''
last(['foo', 'bar']) => 'bar'
'''
return getindex(array, -1, default)
def getvalue(dic, *keys, default=None):
'''
dic = { 'foo': { 'bar': True }}
getvalue(dic, 'foo', 'bar') => True
'''
try:
return reduce(getitem, keys, dic)
except KeyError:
return default
def typeDict(to_type=None, **kwargs):
'''
typeDict({foo': { 'bar': True }})
typeDict(foo={ 'bar': True })
'''
# create native dict from args
dic = to_type or kwargs
# create TypeDict instance
get = lambda self, *args,: typed(getvalue(dic, *args))
return type('TypeDict', (), {
'get': get, # dic.get('bar', 'foo') => True
'native': dic, # dic.native => {foo': { 'bar': True }}
'__getattr__': get # dic.bar.foo => True
})()
def typeList(to_type, *args):
'''
typeList(['foo', 'bar'])
typeList('foo', 'bar')
'''
# create native list from args
if isinstance(to_type, (list, tuple)):
array = list(to_type)
else:
array = [to_type]
array += list(args)
# create TypeList instance
get = lambda self, i: typed(getindex(array, i))
return type('TypeList', (), {
'first': typed(first(array)), # array.first => 'foo'
'last': typed(last(array)), # array.last => 'bar'
'get': get, # array.get(42) => None
'native': array # array.native => ['foo', 'bar']
})()
def typed(to_type=None, *args, **kwargs):
'''
array = typed(['foo', {'foo': 'bar'}, ['bar']])
array = typed('foo', {'foo': 'bar'}, ['bar'])
array.last.first => 'bar'
array.get(1).foo => 'bar'
'''
if isinstance(to_type, (list, tuple)) or args:
return typeList(to_type, *args)
elif isinstance(to_type, dict) or kwargs:
return typeDict(to_type, **kwargs)
return to_type
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment