列表值的字典理解
Dictionary Comprehension for list values
我想知道是否有更 Pythonic 的方式来执行以下操作,也许使用字典理解:
A = some list
D = {}
for i,v in enumerate(A):
if v in D:
D[v].append(i)
else:
D[v] = [i]
使用 defaultdict
:
from collections import defaultdict
D = defaultdict(list)
[D[v].append(i) for i, v in enumerate(A)]
使用setdefault
:
D = {}
[D.setdefault(v, []).append(i) for i, v in enumerate(A)]
我想不出在不对数据进行排序的情况下使用字典理解的任何意义:
from itertools import groupby
from operator import itemgetter
{v: ids for v, ids in groupby(enumerate(sorted(A)), itemgetter(1))}
表演:
from collections import defaultdict
from itertools import groupby
from operator import itemgetter
from random import randint
A = tuple(randint(0, 100) for _ in range(1000))
def one():
D = defaultdict(list)
[D[v].append(i) for i, v in enumerate(A)]
def two():
D = {}
[D.setdefault(v, []).append(i) for i, v in enumerate(A)]
def three():
{v: ids for v, ids in groupby(enumerate(sorted(A)), itemgetter(1))}
from timeit import timeit
for func in (one, two, three):
print(func.__name__ + ':', timeit(func, number=1000))
结果(一如既往,最简单的获胜):
one: 0.25547646999984863
two: 0.3754340969971963
three: 0.5032370890003222
您可以执行以下操作
d = collections.defaultdict(list)
for i,v in enumerate(A):
d[v].append(i)
可以看到生成的字典的值为list
s,其中的元素是在遍历时产生的。如果硬要做dict comp,就得先找到所有的(value, [indices])
,然后再对[(k,[v])]
做dict comp,这就是多余的杂技,没有任何好处。
我想知道是否有更 Pythonic 的方式来执行以下操作,也许使用字典理解:
A = some list
D = {}
for i,v in enumerate(A):
if v in D:
D[v].append(i)
else:
D[v] = [i]
使用 defaultdict
:
from collections import defaultdict
D = defaultdict(list)
[D[v].append(i) for i, v in enumerate(A)]
使用setdefault
:
D = {}
[D.setdefault(v, []).append(i) for i, v in enumerate(A)]
我想不出在不对数据进行排序的情况下使用字典理解的任何意义:
from itertools import groupby
from operator import itemgetter
{v: ids for v, ids in groupby(enumerate(sorted(A)), itemgetter(1))}
表演:
from collections import defaultdict
from itertools import groupby
from operator import itemgetter
from random import randint
A = tuple(randint(0, 100) for _ in range(1000))
def one():
D = defaultdict(list)
[D[v].append(i) for i, v in enumerate(A)]
def two():
D = {}
[D.setdefault(v, []).append(i) for i, v in enumerate(A)]
def three():
{v: ids for v, ids in groupby(enumerate(sorted(A)), itemgetter(1))}
from timeit import timeit
for func in (one, two, three):
print(func.__name__ + ':', timeit(func, number=1000))
结果(一如既往,最简单的获胜):
one: 0.25547646999984863
two: 0.3754340969971963
three: 0.5032370890003222
您可以执行以下操作
d = collections.defaultdict(list)
for i,v in enumerate(A):
d[v].append(i)
可以看到生成的字典的值为list
s,其中的元素是在遍历时产生的。如果硬要做dict comp,就得先找到所有的(value, [indices])
,然后再对[(k,[v])]
做dict comp,这就是多余的杂技,没有任何好处。