【问题标题】:List comprehension from a set whose elements are tuples composed of two tuples来自一个集合的列表理解,其元素是由两个元组组成的元组
【发布时间】:2021-07-22 00:12:58
【问题描述】:

我有一个庞大的元组列表,每个元组都包含另外两个元组,例如

lst = [((0,2,1), (2,1,3)), ((3,2,1), (0,1,1)), ...]

此列表中的许多元素在某些条件下是不可接受的,我正在尝试创建一个由满足这些条件的元素组成的新列表。除其他外,我想删除那些左(或右)元组包含零但右(或左)元组在同一位置没有零的元素。此外,那些左元组包含两个连续的非零数字(在给定范围内)并且位于右元组中与重复出现的位置相同位置的数字不是 1。为此,我尝试过:

acceptable_lst = [elem for elem in lst for j in range(3) if not ((elem[0][j] == 0 and
                  elem[1][j] != 0) or (j < 2 and elem[0][j] != 0 and elem[0][j] == elem[0][j+1]
                  and elem[1][j+1] != 1)]

当我将此代码应用于例如时

lst = [((3,2,2), (1,2,3)),
       ((0,1,3), (2,2,3)),
       ((1,1,2), (3,3,3)),
       ((0,2,2), (3,3,3)),
       ((2,2,1), (3,1,3))]

我想得到:

acceptable_lst = [((2,2,1), (3,1,3))]

为什么? lst 中的第一个元素在左侧元组中的代表为 2,第二个在第三个位置中为 2,但在右侧元组中的第三个元素不是 1。第二个元素在左元组和右元组相同位置的非零,以此类推...只有lst中的最后一个元素满足上述条件。

然而我得到的是

[((3, 2, 2), (1, 2, 3)),
 ((3, 2, 2), (1, 2, 3)),
 ((0, 1, 3), (2, 2, 3)),
 ((0, 1, 3), (2, 2, 3)),
 ((1, 1, 2), (3, 3, 3)),
 ((1, 1, 2), (3, 3, 3)),
 ((0, 2, 2), (3, 3, 3)),
 ((2, 2, 1), (3, 1, 3)),
 ((2, 2, 1), (3, 1, 3)),
 ((2, 2, 1), (3, 1, 3))]

这表明我的代码完全错误。我怎样才能实现我需要的东西?

【问题讨论】:

  • 添加几个例子来说明你的情况!
  • 将其分解为子问题:编写一个函数,给定一个由两个元组组成的元组(即列表中的一个元素),如果应该保留它,则返回True,如果它返回False它应该被丢弃。然后你可以写[elem for elem in original_list if your_function(elem)] 或等效的list(filter(your_function, original_list))
  • 另外,该列表理解缺少右括号,这会导致语法错误
  • FWIW,好像有一个问题是for j in range(3),每elem重复3次
  • 我的原始列表:lst = [((3,2,2),(1,2,3)), ((0,1,3),(2,2,3)) , ((1,1,2),(3,3,3)), ((0,2,2),(3,3,3)), ((2,2,1),(3,1 ,3))]

标签: python tuples list-comprehension


【解决方案1】:

检查函数的有效性

def valid(elemLeft, elemRight):
    lastItem = None
    for i in range(3):
        if elemLeft[i] == 0 and elemRight[i] != 0:
            return False

        if lastItem != None:
            if elemLeft[i] == lastItem and elemRight[i] != 1:
                return False

        lastItem = elemLeft[i]
    
    return True

lst = [((3,2,2),(1,2,3)), ((0,1,3),(2,2,3)), ((1,1,2),(3,3,3)), ((0,2,2),(3,3,3)), ((2,2,1),(3,1,3))]
acceptable_lst = [elem for elem in lst if valid(elem[0],elem[1])]
print(acceptable_lst)

【讨论】:

【解决方案2】:

您在列表理解中执行了两个 for 循环。

[ elem for elem in lst for j in range(3) if condition ]

相当于:

out_list = []
for elem in lst:
    for j in range(3):
        if condition:
            out_list.append(elem)

如果你必须为此任务使用列表推导,你可以修改它:

import numpy as np

acceptable_lst = [elem for elem in lst 
                  if not (np.any([(elem[0][j] == 0 and elem[1][j] != 0) for j in range(3)])) 
                    and not np.any([(j < 2 and elem[0][j] != 0 and elem[0][j] == elem[0][j+1] and elem[1][j+1] != 1) for j in range(3)])]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 2022-06-15
    • 2015-10-30
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多