-
-
Save rafaelcaricio/2009266 to your computer and use it in GitHub Desktop.
| *.swp | |
| *.pyc | |
| *.pyo |
| #!/usr/bin/python | |
| # -*- coding: utf-8 -*- | |
| import json | |
| cars = json.loads(open('./fixtures/fipe_carro.json').read()) | |
| tree = {} | |
| for v in cars: | |
| for name in v['translated_names']: | |
| for i in xrange(1, len(name) + 1): | |
| tree_node = tree.get(name[:i], []) | |
| tree_node.append(v) | |
| tree[name[:i]] = tree_node |
| #!/usr/bin/python | |
| # -*- coding: utf-8 -*- | |
| import json | |
| cars = json.loads(open('../api/fixtures/fipe_carro.json').read()) | |
| class Tree(dict): | |
| def __init__(self, *args, **kwargs): | |
| self.current_values = [] | |
| def __getitem__(self, key): | |
| node = super(Tree, self).__getitem__(key[0]) | |
| if len(key[1:]) > 0: | |
| return node[key[1:]] | |
| return node.current_values | |
| def push(self, key, obj): | |
| node = self.get(key[0], Tree()) | |
| node.current_values.append(obj) | |
| if len(key[1:]) > 0: | |
| node.push(key[1:], obj) | |
| self[key[0]] = node | |
| @classmethod | |
| def from_list(cls, objects, get_index): | |
| new_tree = cls() | |
| for obj in objects: | |
| key = get_index(obj) | |
| if hasattr(key, 'next'): | |
| for k in key: | |
| new_tree.push(k, obj) | |
| else: | |
| new_tree.push(key, obj) | |
| return new_tree | |
| tree = Tree.from_list(cars, lambda car: (name for name in car['translated_names'])) | |
| print tree['coupe-4'] | |
| #!/usr/bin/python | |
| # -*- coding: utf-8 -*- | |
| import json | |
| class Tree(dict): | |
| def __setitem__(self, key, obj): | |
| """ | |
| Pushes a new object in the tree. | |
| """ | |
| for i in xrange(3, len(key) + 1): | |
| tree_node = self.get(key[:i], []) | |
| super(Tree, self).__setitem__(key[:i], tree_node) | |
| tree_node.append(obj) | |
| @classmethod | |
| def from_list(cls, objects, get_key): | |
| """ | |
| Build tree form a list of objects. | |
| """ | |
| tree = cls() | |
| for obj in objects: | |
| key_value = get_key(obj) | |
| if isinstance(key_value, list): | |
| for key in key_value: | |
| tree[key] = obj | |
| else: | |
| tree[key_value] = obj | |
| return tree | |
| cars = json.loads(open('../api/fixtures/fipe_carro.json').read()) | |
| tree = Tree.from_list(cars, lambda car: car['translated_names']) | |
| print tree['attracti.'] |
| #!/usr/bin/python | |
| # -*- coding: utf-8 -*- | |
| from api.nary import Tree | |
| import json | |
| cars = json.loads(open('./fixtures/fipe_carro.json').read()) | |
| tree = Tree.from_list(cars, lambda vehicle: vehicle['translated_names']) |
Analisando o problema tive outra ideia. As buscas na árvore nunca são menores que 3 caracteres. Com a ideia de implementar usando dict dá pra fazer uma otimização a mais e bem simples. Só colocar no dict chaves com três ou mais caracteres. Peguei a implementação de @vbmendes e mudei algumas coisas, mas a mudança mais interessante foi ter colocado essa otimização nas chaves.
Com isso a árvore em memória da implementação test_hash_obj.py gastou 22,2 mb de memória RAM.
Agora ficou mais natural usar a árvore:
from test_hash_obj import Tree
tree = Tree()
tree['casa'] = 'casa'
tree['casca'] = 'casca'
tree['casarao'] = 'casarao'
print treeEu tinha pensado nessa ideia de sobrescrever o setitem, só não tinha conseguido chegar a uma boa solução para a chave que seria setada, visto que um objeto pode ter mais de uma chave. Eu criei um projeto para centralizar esses testes. Vou comittar o que eu tenho aqui e te dar permissão de committer por que o gist não dá tanto poder assim.
Massa, cria ai!
Abs.
Criado. Já te coloquei como colaborador.
Ah sim, eu tentei manter a forma de inserção da primeira implementação ( test_nary.py ). E usar a ideia de dicionários. Tô pensando em outro jeito aqui.