【问题标题】:How to pass list of tuples through a object method in python如何通过python中的对象方法传递元组列表
【发布时间】:2023-03-03 07:24:23
【问题描述】:

遇到这个令人沮丧的问题,我想通过以下列表中的元组 通过我创建的类的另一个实例列表上的方法

list_1=[(0, 20), (10, 1), (0, 1), (0, 10), (5, 5), (10, 50)]
instances=[instance[0], instance[1],...instance[n]]
results=[]
pos_list=[]
for i in range(len(list_1)):
    a,b=List_1[i]
    result=sum(instance.method(a,b) for instance in instances)
    results.append(result)
    if result>=0:
        pos_list.append((a,b))
print(results)
print(pos_list)

问题是所有实例都采用 same 元组,而我希望第一个实例上的方法采用第一个元组,依此类推。 如果总和>0,我最终希望看到它附加到新列表(pos_list)。

有人知道我怎样才能正确地迭代这个吗?


编辑 如果我也打印总和的结果会更清楚。

基本上我希望总和执行如下:

result = instance[0].method(0,20), instance[1].method(10,1), instance[2].method(0,1), instance[3].method(0,10), instance[4].method(5,5), instance[5].method(10,50)

对于信息,该方法只是两个值的 +/- 乘积,具体取决于实例的属性。 所以上面的结果是:

result = [0*20 - 10*1 - 0*1 + 0*10 - 5*5 + 10*50] = [465]
pos_list=[(0, 20), (10, 1), (0, 1), (0, 10), (5, 5), (10, 50)]

除了实际做的是对所有实例使用相同的元组,如下所示:

result = instance[0].method(0,20), instance[1].method(0,20), instance[2].method(0,20), instance[3].method(0,20), instance[4].method(0,20), instance[5].method(0,20)
result = [0*20 - 0*20 - 0*20 + 0*20 - 0*20 + 0*20] = [0]
pos_list=[]

对于 (10,1) 等等。

如何使它像第一个示例一样工作?

【问题讨论】:

  • 嗨!你能更明确地说明总和吗?是否要将元组第一个元素上第一个实例的method 的结果与元组第二个元素上第二个实例的method 的结果相加,等等?并对list_1 的每一项重复此操作,再次考虑整个列表l1
  • 嗨,是的,没错!我的问题是每个循环的所有实例都使用一个元组,我试图考虑如何让它一个接一个地进行(即第一个实例到第一个元组等等)
  • 但是以这种方式每次迭代的总和结果都会相同,因此将所有元素附加到pos_list 或不附加。
  • 知道我可以做些什么不同的事情来得到我想要的吗?
  • 您应该更详细地解释您的想法,添加输入和预期输出的示例

标签: python-3.x list object iterator instance


【解决方案1】:

您可以使用zip 计算您的总和,以生成所有对应实例和元组对。

result=sum(instance.payout(*t) for instance, t in zip(instances, List_1))

zip 将在到达两个迭代器中最短的那个时停止。因此,如果您有 10 个实例和 100 个元组,zip 将使用两个列表的前 10 个元素仅生成 10 对。

我在您的代码中看到的问题是您正在计算List_1 的每个元素的总和,因此如果payout 在相同的输入下总是产生相同的结果(例如,它没有记忆或随机性), result 的值在每次迭代中都相同。所以,最后,results 将由相同的值组成,重复次数等于List_1 的长度,而pos_list 将包含所有(总和大于 0)或无(总和小于或等于零)的输入元组。

相反,如果 List_1 的项目本身是列表或元组,那将是有意义的:

List_1 = [
    [(0, 1), (2, 3), (4, 5)],
    [(6, 7), (8, 9), (10, 11)],
    [(12, 13), (14, 15), (16, 17)],
]

因此,在这种情况下,假设您的 instances 类是这样的:

class Goofy:
    def __init__(self, positive_sum=True):
        self.positive_sum = positive_sum

    def payout(self, *args):
        if self.positive_sum:
            return sum(args)
        else:
            return -1 * sum(args)

instances = [Goofy(i) for i in [True, True, False]]

你可以用这种方式重写你的代码:

results=[]
pos_list=[]
for el in List_1:
    result = sum(g.payout(*t) for g, t in zip(instances, el))
    results.append(result)
    if result >= 0:
        pos_list.append(el)

运行之前的代码,results 将是:

[-3, 9, 21]

pop_list:

[[(6, 7), (8, 9), (10, 11)], [(12, 13), (14, 15), (16, 17)]]

如果你只对pop_list感兴趣,你可以只用一行压缩你的代码:

pop_list = list(filter(lambda el: sum(g.payout(*t) for g, t in zip(instances, el)) > 0, List_1))

【讨论】:

    【解决方案2】:

    非常感谢以上内容!我现在可以工作了。 鉴于我的方法有更多内容,因此无法使用 args 但使用 zip 是它点击的原因

    import random
    rand=random.choices(list_1, k=len(instances))
    
    results=[]
    pos_list=[]
    for r in rand:
        x,y=r
    result=sum(instance.method(x,y) for instance,(x,y) in zip(instances, rand))
    results.append(result)
    if result>=0:
        pos_list.append(rand)
    print(results)
    print(pos_list)
    

    例如列表

    rand=[(20, 5), (0, 2), (0, 100), (2, 50), (5, 10), (50, 100)]
    

    这将返回以下内容

    results=[147]
    pos_list=[(20, 5), (0, 2), (0, 100), (2, 50), (5, 10), (50, 100)]
    

    这正是我想要的。再次感谢!

    【讨论】:

      猜你喜欢
      • 2022-01-02
      • 2011-05-11
      • 2015-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多