【问题标题】:Python using combinations to sum values in a tuple in a list in a dictionary?Python使用组合对字典列表中的元组中的值求和?
【发布时间】:2017-04-14 16:01:13
【问题描述】:

我正在尝试对字典中元组列表中的值组合求和。例如,我的字典包含:

dict = {1: [(2, 2), (4, 3), (6, 1), (7, 1), (8, 3)], 2: [(4, 1), (5, 3), (1, 2)],...} 

并继续输入多个条目。我正在尝试将每个条目的元组的第二个值以最多为 4 的多个组合相加。因此,对于条目 1,所需的输出将是:

{1: [(2, 6, 3), (2, 7, 3), (4, 6, 4), (4, 7, 4), (6, 7, 2), (8, 6, 4), (8, 7, 4)]

这里元组中的第三个值是前一个元组的第二个值的组合之和,这个元组的第一个和第二个值是前一个元组的关联第一个值。

我尝试了以下代码:

for key, value in dict.items():
    object1 = key
    mylist = value
    for tup in mylist:
         object2 = tup[0]
         pair = tup[1]
         combo = itertools.combinations(tup[1],2)
         sum = {k:sum(j for _,j in v) for k,v in combo}
         if sum <= 4:
             print(sum)

我得到了错误

'numpy.float64' object is not iterable

我认为我的错误源于“组合”以及我对 itertools 的使用。我不确定我是否只需要修复我的代码的这一部分,或者我的方法是否偏离了基础。

【问题讨论】:

  • 我似乎无法理解这个问题。该错误是由于尝试迭代不可迭代的。但是代码似乎没有接受您提供的输入。
  • 什么是mylist
  • “我认为我的错误源于“combo”” 回溯将指示错误是从哪一行引发的,我认为这与问题有关。
  • 您的代码中至少有几个错误会导致问题,尽管不是您想的那样。因此,您已将名称 sum 分配给您的 dict 理解结果。这意味着sum &lt;= 4 会抛出一个错误,即使没有,下次你尝试使用sum 函数 时你将无法使用,因为sum 现在是一个字典
  • 另外,如果tupnumpy.float64 对象的元组,那么tup[0] 是某个数字,它是不可迭代的,它会抛出你看到的错误。

标签: python tuples combinations


【解决方案1】:

是的,您可以使用itertools.combinations 执行此操作,但您必须将正确的参数传递给它。 :) 您需要将元组列表传递给它,以便它可以生成元组对。您可以使用推导式来做到这一点,但我认为使用传统的 for 循环更容易阅读。

正如其他人所提到的,您的代码还有其他问题,除了没有将正确的东西传递给combinations。主要是您将字典分配给名称sum,这会影响您也尝试使用的sum 内置函数。而且您还尝试将该字典与整数 4 进行比较,这没有多大意义。 :)

无论如何,这里有一些代码可以满足您的需求。请注意,在您的预期输出中,您弄乱了最后两个元组:(8, 6, 4)(8, 7, 4) 应该分别是 (6, 8, 4)(7, 8, 4)

from itertools import combinations

a = {
    1: [(2, 2), (4, 3), (6, 1), (7, 1), (8, 3)], 
    2: [(4, 1), (5, 3), (1, 2)],
}

new_dict = {}

for k, seq in a.items():
    c = []
    for (u,v), (x,y) in combinations(seq, 2):
        total = v + y
        if total <= 4:
            c.append((u, x, total))
    new_dict[k] = c

for k, seq in new_dict.items():
    print(k, seq)

输出

1 [(2, 6, 3), (2, 7, 3), (4, 6, 4), (4, 7, 4), (6, 7, 2), (6, 8, 4), (7, 8, 4)]
2 [(4, 5, 4), (4, 1, 3)]

combinations(seq, 2) 产生成对的元组,我们可以将这些元组解包成它们各自的数字

for (u,v), (x,y) in combinations(seq, 2):

我们可以做类似的事情

for t0, t1 in combinations(seq, 2):

然后在单独的步骤中解压缩 t0t1 元组,或者只是使用索引来获取它们的项目。例如,

for t0, t1 in combinations(seq, 2):
    total = t0[1] + t1[1]
    if total <= 4:
        c.append((t[0], t[1], total))

但我认为以前的方式不那么混乱。


但如果你坚持用推导式来做这一切,你可以:

new_dict = {k: [(u, x, v+y) for (u,v), (x,y) in combinations(seq, 2) if v+y <= 4]
    for k, seq in a.items()}

请注意,这比以前的版本效率低,因为它为通过v+y &lt;= 4 测试的每个组合计算两次v+y

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-06
    • 1970-01-01
    • 1970-01-01
    • 2015-10-24
    相关资源
    最近更新 更多