我有以下数据结构:
data = [[{'Posit': '0', 'R': '0', 'B': '0', 'G': '255'}, {'Posit': '1000', 'R': '255', 'B': '0', 'G': '0'}],
[{'Posit': '0', 'R': '0', 'B': '0', 'G': '255'}, {'Posit': '1000', 'R': '255', 'B': '0', 'G': '0'}],
[{'Posit': '0', 'R': '0', 'B': '0', 'G': '255'}, {'Posit': '1000', 'R': '255', 'B': '0', 'G': '0'}],
[{'Posit': '0', 'R': '255', 'B': '0', 'G': '255'}, {'Posit': '1000', 'R': '0', 'B': '255', 'G': '0'}],
[{'Posit': '0', 'R': '0', 'B': '0', 'G': '255'}, {'Posit': '1000', 'R': '255', 'B': '0', 'G': '0'}],
[{'Posit': '0', 'R': '0', 'B': '0', 'G': '255'}, {'Posit': '1000', 'R': '255', 'B': '0', 'G': '0'}],
[{'Posit': '0', 'R': '0', 'B': '0', 'G': '255'}, {'Posit': '1000', 'R': '255', 'B': '0', 'G': '0'}],
[{'Posit': '0', 'R': '0', 'B': '0', 'G': '255'}, {'Posit': '1000', 'R': '255', 'B': '0', 'G': '0'}]]
我想在上面的数据结构中找到最常用的词典列表。
我的第一个想法是使用most_common
中的collections.Counter
函数,但
from collections import Counter
c = Counter()
for point in data:
c[point] += 1
因TypeError
而失败,因为列表不可用。
我的下一个想法是将列表转换为元组,因为元组是不可变的
from collections import Counter
c = Counter()
for point in data:
c[tuple(point)] += 1
然后我得到一个TypeError
说字典也是不可用的。
那么什么是Pythonic的方法来实现我想要的呢?
答案 0 :(得分:1)
您可以使用Counter
,但您必须将列表转换为元组和字典,并将其转换为元组的元组元组(元组键值的元组,以便能够比较两个字典)。
>>> Counter(tuple(tuple(sorted(d.items())) for d in a) for a in data).most_common()
[(((('B', '0'), ('G', '255'), ('Posit', '0'), ('R', '0')),
(('B', '0'), ('G', '0'), ('Posit', '1000'), ('R', '255'))),
7),
(((('B', '0'), ('G', '255'), ('Posit', '0'), ('R', '255')),
(('B', '255'), ('G', '0'), ('Posit', '1000'), ('R', '0'))),
1)]
正如@Marcin正确评论tuple(sorted(d.items()))
可以替换为更合适的frozenset(d.items())
:
>>> Counter(tuple(frozenset(d.items()) for d in a) for a in data).most_common()
[((frozenset([('Posit', '0'), ('B', '0'), ('G', '255'), ('R', '0')]),
frozenset([('R', '255'), ('G', '0'), ('B', '0'), ('Posit', '1000')])),
7),
((frozenset([('Posit', '0'), ('R', '255'), ('B', '0'), ('G', '255')]),
frozenset([('B', '255'), ('G', '0'), ('R', '0'), ('Posit', '1000')])),
1)]
答案 1 :(得分:1)
from collections import namedtuple, Counter
# You can probably think of a better name than this
datum = namedtuple('datum', 'Posit R B G')
Counter(tuple(datum(**d) for d in a) for a in data).most_common()
# You might actually want to make the conversion permanent;
# the data is possibly easier to work with that way given the
# fixed key structure, and it should save memory too