【问题标题】:How to slice a list (or create sublists) based on elements in original list that differ by a set value如何根据原始列表中与设定值不同的元素对列表进行切片(或创建子列表)
【发布时间】:2018-10-16 04:33:28
【问题描述】:

这是我第一次在这里问问题,所以请不要烤我太多,因为我试图让事情发生变化。

我正在使用 Python 3 编写一些代码。因此,在我的代码中,我生成了一个列表。为了具体起见,假设我正在使用以下列表:

a = [3344, 3354, 3364, 3364, 3374, 3374, 3384, 3384, 3394, 3394, 3404, 3404, 3414, 3414, 3424, 3434]

我想将此列表分类为以下子列表:

sub1 = [3344, 3354, 3364, 3374]
sub2 = [3364, 3374, 3384, 3394]
sub3 = [3384, 3394, 3404, 3414]
sub4 = [3404, 3414, 3424, 3434]

所以,我想根据已知值不同的元素将原始列表排序为子列表,在本例中为 10。

我无法使用基于索引的切片,也无法实现任何类型的 lambda 函数来完成此操作。我搜索了 Stack Overflow 的深度,并没有发现任何特别有用的东西。

感谢您的帮助。

更新:

我想添加更多信息,以消除由于我的语言缺乏特异性而导致的任何混淆。目标是从原始列表中生成包含四个元素的子列表,子列表中的元素相差 10。

为了更好地解释我在这里要完成的工作,我将提供第二个列表和所需的输出子列表。

b = [3384, 3404, 3344, 3394, 3374, 3414, 3354, 3404, 3384, 3424, 3364, 3414, 3394, 3364, 3434, 3374]

所需的输出如下所示:

sublist1 = [3344, 3354, 3364, 3374]
sublist2 = [3364, 3374, 3384, 3394]
sublist3 = [3384, 3394, 3404, 3414]
sublist4 = [3404, 3414, 3424, 3434]

我需要能够生成此输出,因为这些子列表稍后将用作不同函数的输入值...必须捕获退化值。

我希望这能解决问题!

【问题讨论】:

  • 给定的列表a 是否总是排序的,并且所有元素都相差已知值(10)?
  • 列表a在这里排序。排序之前的结构是随机的,这意味着元素不会总是出现在某个索引处。元素总是会因已知值而不同。
  • 这里还不清楚你想要什么。您是否想要可以从输入列表构造的所有连续 4 个数字(以 10 分隔)的集合?如果是这样,您为什么不想要子列表[3354, 3364, 3374, 3384] 或[3374, 3384, 3394, 3404]?此外,输入是否总是使用 +10 间距(例如,像这里一样以 4 结尾)?是否会有大于 10 的间隙? (即,您只是想过滤掉重复项还是解决空白?)
  • 很抱歉,不清楚。基本上,我试图将四个相关的行位置(由给定子列表的四个元素表示)组合在一起。每个子列表代表一组这些相关的行位置。在这个给定的例子中,我们有四个组。排序列表中的第一个值(称为 x)将始终是第一个子列表的第一个值,该子列表必须有四个均匀分布的元素,在本例中为 10。那么第一个子列表将是 [x, x+ 10, x+20, x+30]。子列表中元素之间的间距始终是一个设定的数字,可以是 1-50 之间的任何数字。
  • 对于额外的评论,我深表歉意,但有字符限制。我正在努力解决差距。为了简单起见,我选择了差距为 10,但我想我无意中让它变得更复杂了。原始列表中的第一个重复元素将始终是 sublist2 的第一个元素。

标签: python python-3.x list


【解决方案1】:

您可以使用嵌套的for 循环将a 中的项目附加到现有的子列表中,该子列表的长度小于 4 且最后一个项目比该项目小 10,或者使用该项目创建一个新的子列表:

l = []
for i in a:
    for s in l:
        if len(l) < 4 and s[-1] + 10 == i:
            s.append(i)
            break
    else:
        l.append([i])

鉴于您的示例输入,l 将变为:

[
    [3344, 3354, 3364, 3374],
    [3364, 3374, 3384, 3394],
    [3384, 3394, 3404, 3414],
    [3404, 3414, 3424, 3434]
]

请注意,您的预期输出不正确,因为您的输入 a 中的项目可以排序到两个子列表中,而不会破坏所有相邻项目相差 10 的规则。

【讨论】:

  • 代码中的所有逻辑都是正确的,但是,我正在尝试生成预期的输出......因此,基于初始列表,我正在尝试生成四个子列表。我跳出来的标准是相差十。我想上面列出的输出将更准确地称为“所需输出”。抱歉!
  • 所以你需要更清楚地定义你的规则,这会产生预期的输出。否则,没有明确的理由进一步分解这两个子列表。
  • 抱歉!我仍在努力学习白话,所以我可以有效地与真正的程序员交流我想要完成的事情......我不确定如何更好或更清楚地定义我的规则,因为我的规则是一个“功能”的输出......我正在尝试提出一个规则,允许我在给定初始列表的情况下生成所需的子列表。
  • 我已经更新了我的答案,您的新要求是子列表的最大长度为 4。
  • 我继续测试了您的代码。当我运行它时,我得到以下 l 的输出: l = [[3344, 3354, 3364, 3374, 3384, 3394, 3404, 3414, 3424, 3434], [3364, 3374, 3384, 3394, 3404,第3414章]
【解决方案2】:

将sorted 与set 和一个循环一起使用

b = [3384, 3404, 3344, 3394, 3374, 3414, 3354, 3404, 3384, 3424, 3364, 3414, 3394, 3364, 3434, 3374]

lst = sorted(set(b))
for i in range(4):
    print(lst[i*2:i*2+4])
[3344, 3354, 3364, 3374]
[3364, 3374, 3384, 3394]
[3384, 3394, 3404, 3414]
[3404, 3414, 3424, 3434]

【讨论】:

  • 效果很好...您愿意用 lst[i*2:i*2+4] 解释您的打印语句中发生了什么吗?
  • @brandon 抱歉,喝了几杯,我是我,但我会试着解释一下,所以基本上这个列表从初始数字开始以 10 为增量,每行末尾都有一个双精度数,如果我们取集合,我们删除双精度并有一个递增 10 的列表,但我们的输出是 4 行,开始递增 20,因此对于范围 4 中的 i 表示我们想要的 4 行,我们将 i 乘以 2 以创建 20 的间隙,所以我们得到 0*2 然后 2, 4 , 6 我们创建一个包含 4 个项目的列表,对不起,早上会更好地解释 heheh ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-19
相关资源
最近更新 更多