【问题标题】:Python - How to loop through a list while checking forward elements?Python - 如何在检查前向元素时遍历列表?
【发布时间】:2018-03-13 02:13:29
【问题描述】:

目前我正在查看如下列表: [[x, y, z], [x1, y1, z1], [x2, y2, z2]...]

我想循环比较 x1 和 x2 以及 y1 和 y2,如果两者相等,我想将 z2 的值添加到 z1 并将它们添加到一个新列表中。

if x1 == x2 and y1 == y2: list.append(x1, y1, z1+z2)

但是我需要它是连续的,这样如果 x3 和 y3 也等于 x2 和 y2 那么它们将像以前一样被添加到一起,并且仅在 x 和 y 的下一个值为 no 时才添加到新列表中更长的时间等于现在的。

实际上,如果一个链 x1 == x2 == x3 == x4 and y1 == y2 == y3 == y4 评估为真,那么新列表应该只包含一个条目 [x, y, z1 + z2 + z3 + z4]

到目前为止,我已经在 for 循环(和列表理解)中尝试了一个递归函数,但是我遇到了各种各样的问题,我不知道人们通常是如何做这种事情的。

期望的输出:

[[x1, y1, z1+z2+z3+z4], [x5, y5, z5], [x6, y6, z6+z7]...]

到目前为止我的代码(有点乱。我在中途感到沮丧并尝试更改很多代码。):

list = [function(oldList, i) for i in range(len(oldList))]

def isNextElementEqual(list, index, totalTimeSpent = 0, count = 0):
    if list[index][2] == list[index + 1][2] and list[index][0] == list[index+1][0] and index+1 < len(list):
        totalTimeSpent += list[index][1]
        count += 1
        isNextElementEqual(list, index + 1, totalTimeSpent, count)
    elif count > 0:
        return [list[index][0], totalTimeSpent, list[index][2]]

【问题讨论】:

  • 你能告诉我们你到目前为止做了什么吗?没有您尝试过的证明,我们不能只为您工作
  • 请发布您想要的输出。
  • 好的,我马上编辑帖子。
  • 如果 y1=y2,但 x1 != x2 怎么办?
  • 如果 x1 != x2,我不需要将任何数据添加到新列表中,因此不会返回。

标签: python python-3.x list loops for-loop


【解决方案1】:

使用itertools.groupby

import itertools

l = [[1, 2, 3], [1, 2, 4], [1, 3, 5], [1, 3, 6], [1, 3, 7]]

print ([list(key) + [sum(group[-1] for group in groups)] for key, groups in itertools.groupby(l, lambda x: (x[0], x[1]))])

没有列表理解:

result = []
for key, groups in itertools.groupby(l, lambda x: (x[0], x[1])):
    group_res = list(key)
    group_res.append(sum(group[-1] for group in groups))
    result.append(group_res)

输出

[[1, 2, 7], [1, 3, 18]]

另一个例子:

l = [[0, 1, 2], [1, 1, 6], [2, 2, 10], [2, 2, 25], [3, 2, 14]]
[list(key) + [sum(group[-1] for group in groups)] for key, groups in itertools.groupby(l, lambda x: (x[0], x[1]))]

输出

[[0, 1, 2], [1, 1, 6], [2, 2, 35], [3, 2, 14]]

细分:

  • 在这条单线的最里面,您会看到itertools.groupby(l, lambda x: (x[0], x[1]))。它的作用是通过键函数 (lambda x: (x[0], x[1])) 将它找到的连续值分组。在这种情况下,我们按每个列表中的前两个元素对值进行分组。

  • 此函数返回一个元组,该元组由key 和与该键连续匹配的值组成。这允许我们执行list(key) + [sum(group[-1] for group in groups)],它获取键并将其转换为列表,然后将它们最后一个元素的总和附加到列表中。

【讨论】:

  • 我不是很有经验,所以这个解决方案看起来有点混乱,但谢谢!我不知道 itertools 并且它有效!
  • @Weresdrim 对此感到抱歉。列表推导很甜蜜,但很容易成为没有经验的人的噩梦。我已经用循环版本更新了我的帖子,所以你可以更好地了解发生了什么
  • 感谢您付出额外的努力 :)
【解决方案2】:

这需要您检查列表 y 中每个 x 的每个值,这将在计算上变得昂贵。但它有效。

x = [[ 0,  1,  2],
     [ 1,  1,  6],
     [ 2,  2, 10],
     [ 2,  2, 25],
     [ 3,  2, 14]]

y = [x[0]]
for val in x[1:]:
    for ix, i in enumerate(y):
        if val[0] == i[0] and val[1] == i[1]:
            i[2] += val[2]
            break
    else: y.append(val)

print(y)

【讨论】:

  • 输出是:[[0, 1, 2], [1, 1, 12], [2, 2, 45], [3, 2, 28]] 我想要的输出是:[[0, 1, 2], [1, 1, 6], [2, 2, 35], [3, 2, 14]]
  • 对不起,我修好了。
  • for val in x[1:]:for val in x[1:len(x)]: 相同
猜你喜欢
  • 2015-12-20
  • 2011-02-10
  • 2013-08-05
  • 1970-01-01
  • 2019-03-07
  • 2010-11-24
  • 1970-01-01
  • 2020-03-05
  • 2018-09-05
相关资源
最近更新 更多