我有几十万个端点URL,我想为其生成统计信息.例如,我有:
/a/b/c
/a/b/d
/a/c/d
/b/c/d
/b/d/e
/a/b/c
/b/c/d
Run Code Online (Sandbox Code Playgroud)
我想创建一个看起来像这样的字典
{
{'a':
{'b':
{'c': 2 },
{'d': 1 }
},
{'c':
{'d': 1 }
}
},
{'b':
{'c':
{'d': 2}
},
{'d':
{'e': 1}
}
}
}
Run Code Online (Sandbox Code Playgroud)
有什么聪明的方法吗?
编辑
我应该提到路径并不总是3个部分.可能有
/a/b/c/d/e/f/g/h...等等
如果路径在您的示例中看起来都像,那么这将起作用:
counts = {}
for p in paths:
parts = p.split('/')
branch = counts
for part in parts[1:-1]:
branch = branch.setdefault(part, {})
branch[parts[-1]] = 1 + branch.get(parts[-1], 0)
Run Code Online (Sandbox Code Playgroud)
这使用了类似的字典方法setdefault(),get()以避免编写大量的if语句.
请注意,如果具有子目录的路径也可以单独显示,则此操作无效.然后不清楚相应的部分是否counts应包含数字或其他字典.在这种情况下,最好使用元组或自定义类为每个节点存储count和dict.
基本算法保持不变:
class Stats(object):
def __init__(self):
self.count = 0
self.subdirs = {}
counts = Stats()
for p in paths:
parts = p.split('/')
branch = counts
for part in parts[1:]:
branch = branch.subdirs.setdefault(part, Stats())
branch.count += 1
Run Code Online (Sandbox Code Playgroud)
通过一些漂亮的印刷,你得到:
def printstats(stats, indent=''):
print indent + str(stats.count) + ' times'
for (d, s) in stats.subdirs.items():
print indent + d + ':'
printstats(s, indent + ' ')
>>> printstats(counts)
0 times
a:
0 times
c:
0 times
d:
1 times
b:
0 times
c:
2 times
d:
1 times
...
Run Code Online (Sandbox Code Playgroud)
编辑:
我已经修改了我的代码以适应您上面的最后评论(现在没有复杂的数据结构)。
def dictizeString(string, dictionary):
while string.startswith('/'):
string = string[1:]
parts = string.split('/', 1)
if len(parts) > 1:
branch = dictionary.setdefault(parts[0], {})
dictizeString(parts[1], branch)
else:
if dictionary.has_key(parts[0]):
# If there's an addition error here, it's because invalid data was added
dictionary[parts[0]] += 1
else:
dictionary[parts[0]] = 1
Run Code Online (Sandbox Code Playgroud)
[frequency, dictionary]它将存储每个项目的列表。
测试用例
>>> d = {}
>>> dictizeString('/a/b/c/d', d)
>>> dictizeString('/a/b/c/d', d)
>>> dictizeString('/a/b/c/d', d)
>>> dictizeString('/a/b/c/d', d)
>>> dictizeString('/a/b/e', d)
>>> dictizeString('/c', d)
>>> d
{'a': {'b': {'c': {'d': 4}, 'e': 1}}, 'c': 1}
Run Code Online (Sandbox Code Playgroud)
小智 5
旧的结果,但仍然接近谷歌的顶部,所以我会更新:你可以使用 dpath-python 来实现这一点。
$ easy_install dpath
>>> result = {}
>>> for path in my_list_of_paths:
>>> ... dpath.util.set(result, path, SOME_VALUE)
Run Code Online (Sandbox Code Playgroud)
...就是这样。我不明白你用来预先计算终点站上的这些值(1、2等)的数学,但你可以预先计算它并使用路径到值的字典而不是裸列表
>>> x = {'path/name': 0, 'other/path/name': 1}
>>> for (path, value) in x.iteritems():
>>> ... dpath.util.set(result, path, value)
Run Code Online (Sandbox Code Playgroud)
类似的东西会起作用。
| 归档时间: |
|
| 查看次数: |
8575 次 |
| 最近记录: |