计算列表中不考虑顺序的配对数目

3
例如,如果我有以下脚本:
import collections

lst = [['a','b'],['b','a'],['c','d'],['c','d'],['d','c']]

print([(a, b, v) for (a, b),v in collections.Counter(map(tuple,lst)).items()])

我输出的结果是:

我得到的输出:

[('a', 'b', 1), ('b', 'a', 1), ('c', 'd', 2), ('d', 'c', 1)]

我能否修改代码以产生以下输出:
[('a', 'b', 2), ('c', 'd', 3)]

那么,一个不包含对键值对顺序要求的函数?
4个回答

4

使用一个不关心顺序的数据结构。在这种情况下,您将需要使用frozenset而不是常规的set,因为Counter要求它是可哈希的。但基本上,您只需将原始代码中的tuple替换为frozenset即可:

print([(a, b, v) for (a, b),v in collections.Counter(map(frozenset,lst)).items()])

输出:

[('a', 'b', 2), ('d', 'c', 3)]

1
似乎这是最明智的做法;如果你想忽略排序,那么未排序的数据类型似乎是最合适的。被接受的答案通过强制排序始终相同来忽略排序,这似乎是对实际问题的略微不太字面的翻译。 - OliverRadini

2
你可以在计数之前对列表中的每个元素进行排序,像这样:

import collections

lst = [['a','b'],['b','a'],['c','d'],['c','d'],['d','c']]

sorted_lst = [sorted(x) for x in lst]

print([(a, b, v) for (a, b),v in collections.Counter(map(tuple,sorted_lst)).items()])

输出:

[('a', 'b', 2), ('c', 'd', 3)]

2
在获取集合之前对列表进行排序可以解决问题。
import collections

lst = [['a','b'],['b','a'],['c','d'],['c','d'],['d','c']]

sort_list = sorted(x) for x in lst

print([(a, b, v) for (a, b),v in collections.Counter(map(tuple,sort_list)).items()])

1
您可以对键的值进行排序,并在itertools中使用groupby,然后将组中的所有元素sum起来。
import itertools as it
lst = [['a','b'],['b','a'],['c','d'],['c','d'],['d','c']]
output = [(*group,sum(1 for i in elements)) for group,elements in it.groupby(lst,key=lambda x:sorted(x))]
print(output)

输出

[('a', 'b', 2), ('c', 'd', 3)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接