Python 两个列表之间的乘法和数据验证

Python 两个列表之间的乘法和数据验证,python,list,Python,List,我想验证数据并使用两个列表执行一些数学运算。首先,我希望确保每个列表的第一个元素匹配,然后我希望将第二个列表的第二项、第三项和第四项乘以第一个列表的第二项。我想创建一个新列表,然后对该列表的元素求和 列表如下所示: lista = [(1, 500), (2, 600), (3, 333)] listb = [(1, 10, 11, 10.5), (2, 99, 100, 100), (3, 50, 51, 50)] 在创建listc之前,我希望确保每个子列表的第一个元素在列表之间匹配。然后

我想验证数据并使用两个列表执行一些数学运算。首先,我希望确保每个列表的第一个元素匹配,然后我希望将第二个列表的第二项、第三项和第四项乘以第一个列表的第二项。我想创建一个新列表,然后对该列表的元素求和

列表如下所示:

lista = [(1, 500), (2, 600), (3, 333)]

listb = [(1, 10, 11, 10.5), (2, 99, 100, 100), (3, 50, 51, 50)]
在创建listc之前,我希望确保每个子列表的第一个元素在列表之间匹配。然后,我想得到一个列表,该列表将元素相乘,如下所示:

listc = [(1, 5000, 5500, 5250), (2, 59400, 60000, 60000), (3, 16650, 16983, 16650)]
然后我想创建第四个列表,在其中对元素进行汇总,如下所示:

listd = [(6 (doesn't necessarily have to sum this element), 81050, 81650, 81900)]

我一直在研究“zip”函数。我知道该函数可以进行乘法运算,但它如何进行验证?

您可以在Python3中尝试:

from functools import reduce
lista = [(1, 500), (2, 600), (3, 333)]
listb = [(1, 10, 11, 10.5), (2, 99, 100, 100), (3, 50, 51, 50)]
if not all(c == d for (c, e), (d, *h) in zip(lista, listb)) or len(lista) != len(listb) or any(any(b is None for b in i) for i in lista) or any(any(b is None for b in i) for i in listb):
   raise ValueError("lists not validated")
new_listing = [(c, *[d*i for i in e]) for (c, d), (h, *e) in zip(lista, listb) if c == h]
final_listing = [reduce(lambda x, y:(x[0]+y[0], *[a+b for a, b in zip(x[1:], y[1:])]), new_listing)]
print(new_listing)
print(final_listing)
输出:

[(1, 5000, 5500, 5250.0), (2, 59400, 60000, 60000), (3, 16650, 16983, 16650)]
[(6, 81050, 82483, 81900.0)]
编辑:

对初始输入进行排序的解决方案:

from functools import reduce
lista = [(1, 500), (2, 600), (3, 333)]
listb = [(1, 10, 11, 10.5), (2, 99, 100, 100), (3, 50, 51, 50)]
lista = sorted(lista, key=lambda x:x[0])
listb = sorted(listb, key=lambda x:x[0])
new_listing = [(c, *[d*i for i in e]) for (c, d), (h, *e) in zip(lista, listb) if c == h]
final_listing = [reduce(lambda x, y:(x[0]+y[0], *[a+b for a, b in zip(x[1:], y[1:])]), new_listing)]
编辑2:

Python 2.7解决方案:

lista = [(1, 500), (2, 600), (3, 333)]
listb = [(1, 10, 11, 10.5), (2, 99, 100, 100), (3, 50, 51, 50)]
if not all(c == d[0] for (c, e), d in zip(lista, listb)) or len(lista) != len(listb) or any(any(b is None for b in i) for i in lista) or any(any(b is None for b in i) for i in listb):
   raise ValueError("lists not validated")

new_listing = [tuple([c]+[d*i for i in h[1:]]) for (c, d), h in zip(lista, listb) if c == h[0]]
final_listing = [reduce(lambda x, y:tuple([x[0]+y[0]]+[a+b for a, b in zip(x[1:], y[1:])]), new_listing)]

zip
不进行乘法运算
zip
实际上只不过是一种转置。你考虑过换成numpy吗?@cᴏʟᴅsᴘᴇᴇᴅ 是创建类似于常规列表的numpy数组的代码。现在我正在将数据添加到一个空列表中。我会研究制作numpy阵列。我没有投反对票,但这看起来真的很糟糕。它到底在干什么?为什么代码里有这么多意大利面条?天啊。如果
lista
listb
未按第一个元素排序,该怎么办?如果其中一个列表比另一个短怎么办?@vaultah此答案假设OP将使用已发布的已排序输入;但是,我将发布一个考虑到您的问题的解决方案。@cᴏʟᴅsᴘᴇᴇᴅ 我添加了额外的解包以减少这个答案的复杂度。我的数据应该被排序,并且两个列表应该包含相同数量的子列表。但是,如果数据没有验证,我想破坏代码或其他东西。如果任何元素等于“NULL”,我还想抛出一个错误。