簡體   English   中英

Python:在多維列表中獲取所有對和對的頻率

[英]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 ,則ab是列表時,在內部函數中。

更正此問題,您可以使用以下代碼來獲取所需的輸出:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM