[英]Python: Getting all pairs and frequency of pairs in multi-dimensional list
我的多維列表如下所示:
mylist = [[13, 41, 3, 23, 12, 16], [12, 32, 30, 49, 3, 18],
[34, 12, 14, 24, 35, 20], [29, 28, 12, 44, 13, 4],
[31, 44, 6, 49, 5, 39]]
在某些列表中有對(數字為1的數字)。 不在每個列表中:(12,13)在第一個列表中,(34,35)在第三個列表中,(28,29)和(12,13)在第四個列表中。
我要擁有的是獲取所有發現的對,這些對應根據頻率(升序)保存在(排序的)列表中。 在上面的例子中,它看起來如下:
fr_list = [[12,13],[12,13],[28,29],[34,35]]
我寫了以下代碼來找到對
def find_pairs(lst, key):
return [(a,b) for a,b in permutations(lst, 2) if a-b==key]
然后,我嘗試了這個:
fr_list = [find_pairs(mylist,1) for x in mylist]
但是,我收到以下錯誤消息:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <listcomp>
File "<stdin>", line 2, in find_pairs
File "<stdin>", line 2, in <listcomp>
TypeError: unsupported operand type(s) for -: 'list' and 'list'
有人可以幫我嗎? 謝謝。
您的代碼在功能上是正確的,但是您的最終列表理解不正確。 應該是fr_list = [find_pairs(x,1) for x in mylist]
。 在您的情況下,您嘗試將列表列表放入find_pairs函數中。 但是,將mylist
更改為x
意味着您要遍歷每個嵌套列表,而不是遍歷每個嵌套列表的整個列表。
您在這里犯了一個錯誤:
[find_pairs(mylist, 1) for x in mylist]
您每次都向函數而不是子列表傳遞相同的原始列表。 因此, if ab==key
,則a
和b
是列表時,在內部函數中。
更正此問題,您可以使用以下代碼來獲取所需的輸出:
from itertools import permutations, chain
def find_pairs(lst, key):
return [(a, b) for a, b in permutations(lst, 2) if a - b == key]
mylist = [[13, 41, 3, 23, 12, 16], [12, 32, 30, 49, 3, 18],
[34, 12, 14, 24, 35, 20], [29, 28, 12, 44, 13, 4],
[31, 44, 6, 49, 5, 39]]
temp_list = list(chain.from_iterable([find_pairs(x, 1) for x in mylist]))
fr_list = sorted(temp_list, key=lambda x: temp_list.count(x), reverse=True)
print(fr_list)
這就是我要怎么做:
from collections import Counter
from itertools import repeat, chain
def find_diff(lst):
srt = sorted(lst)
return Counter((a, b) for a, b in zip(srt, srt[1:]) if b - a == 1)
pairs = sum((find_diff(item) for item in mylist), Counter())
# Counter({(12, 13): 2, (34, 35): 1, (28, 29): 1, (5, 6): 1})
res = tuple(
chain.from_iterable(repeat(item, count) for item, count in pairs.most_common())
)
# ((12, 13), (12, 13), (34, 35), (28, 29), (5, 6))
如果要尋找1
的差值,那么遍歷排序后的列表會更有效。 然后我將所有內容存儲在Counter
對象中,以便有效地找到最常見的對象。
最后一部分是itertools
魔術,它可以按頻率提取項目及其多樣性。
您可能應該使用排序以避免將每個對與所有其他對進行比較,並使用collections Counter
來匯總結果:
也許是這樣的:
from collections import Counter
def find_pairs(seq):
s = sorted(seq)
all_pairs = []
for first, second in zip(s[:-1], s[1:]):
if second - first == 1:
all_pairs.append((first, second))
return all_pairs
mylist = [[13, 41, 3, 23, 12, 16], [12, 32, 30, 49, 3, 18],
[34, 12, 14, 24, 35, 20], [29, 28, 12, 44, 13, 4],
[31, 44, 6, 49, 5, 39]]
all_pairs = []
for seq in mylist:
all_pairs += find_pairs(seq)
res = []
for pair, qtty in sorted([(k, v) for k, v in Counter(all_pairs).items()], key=lambda x: x[1])[::-1]:
for _ in range(qtty):
res.append(pair)
res
[(12, 13), (12, 13), (5, 6), (28, 29), (34, 35)]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.