按相同的键排序和分组一次

时间:2016-11-14 09:39:09

标签: python python-3.x python-3.5 itertools

我想通过其TLDs

对网址进行分组

我的代码如下所示:

from itertools import groupby
from tldextract import extract

urls = sorted(urls, key=lambda x: extract(x).suffix)
grouped_urls = groupby(urls, key=lambda x: extract(x).suffix)

问题是我调用方法extract 2 * n次(where n == len(urls)),排序时前n次,分组时前n次。 有可能做n次吗?

2 个答案:

答案 0 :(得分:3)

如果您首先将后缀添加为元组,则可以进行排序和分组,而无需按如下方式重新计算:

from itertools import groupby
from tldextract import extract

urls = ["www.example.com", "www.mytest.org", "www.test.com", "www.abc.com"]
urls = [(extract(url).suffix, url) for url in urls]

for k, g in groupby(sorted(urls), key=lambda x: x[0]):
    print k, list(g)

在这个例子中你会得到:

com [('com', 'www.abc.com'), ('com', 'www.example.com'), ('com', 'www.test.com')]
org [('org', 'www.mytest.org')]

答案 1 :(得分:0)

根据您的网址列表的大小,如果您构建了一次所有提取的足够的列表,然后在索引列表上使用索引来排序,则可以加快速度。

from itertools import groupby, count
from tldextract import extract

c1, c2 = count(), count()

lst = [extract(x).suffix for x in urls]
urls = sorted(urls, key=lambda _: lst[next(c1)])
grouped_urls = groupby(urls, key=lambda _: lst[next(c2)])

这样做的一个缺点是,您将O(1)进行2n次索引,如果列表中extract(x)的总时间加快,则速度将提高一些以上远远超过索引新名单的时间。