Python:在多维列表中获取所有对和对的频率

时间:2019-06-01 10:14:25

标签: python 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'

有人可以帮我吗?谢谢。

4 个答案:

答案 0 :(得分:2)

您的代码在功能上是正确的,但是您对最终列表的理解不正确。它应该是fr_list = [find_pairs(x,1) for x in mylist]。在您的情况下,您尝试将列表列表放入find_pairs函数中。但是,将mylist更改为x意味着您要遍历每个嵌套列表,而不是遍历每个嵌套列表的整个列表。

答案 1 :(得分:1)

您在这里犯了一个错误:

[find_pairs(mylist, 1) for x in mylist]

您每次都将相同的原始列表传递给该函数,而不是子列表。因此,执行if a-b==keyab时的内部函数是列表。

更正此错误后,您可以使用以下代码获取所需的输出:

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)

答案 2 :(得分:1)

这就是我要做的事情

<link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css' rel='stylesheet'/>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js'/>
  <script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js'/>


<button type="button" class="btn btn-info" data-toggle="modal" data-target="#Shop">view</button>

<div id="Shop" aria-hidden="true" aria-labelledby="Shop" class="modal fade in" role="dialog" tabindex="-1" display="block">

  <div class="modal-dialog modal-lg">
    <div class="modal-content simpleCart_shelfItem">
      <div class="modal-header">
        <button aria-hidden="true" class="close" data-dismiss="modal" type="button">×</button>
          <h4 class="modal-title"><a expr:href='data:post.href'><data:post.title/></a></h4>
        </div>  
      </div> 
    </div> 

如果您要查找差异<script> $('#Shop').on('show.bs.modal', function (event) { var button = $(event.relatedTarget) var title = &quot;<data:post.title/>&quot;; var modal = $(this) modal.find('.modal-title').text(title) }) </script> ,则可以更有效地遍历排序后的列表。然后我将所有内容存储在Counter对象中,以便有效地找到最常见的对象。

最后一部分是一点itertools魔术,它可以按频率提取项目及其多样性。

答案 3 :(得分:1)

您可能应该使用排序来避免将每一对与所有其他对进行比较,并使用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)]