【问题标题】:How to count items in a conditional loop using enumerate? Python如何使用枚举计算条件循环中的项目? Python
【发布时间】:2020-07-04 12:41:22
【问题描述】:

我有一个列表列表 a 包含 7 个列表,还有一个列表列表 x 包含 2 个列表。我想测试a 中的列表与x 中的列表。

我的目标是逐项比较,找出a 中有多少个列表的所有值都大于x 中的对应项。

条件和计数器检查 a 是否触及 x。注意:我对用列表计算 多少 个项目不感兴趣,例如 a1,touch x1。一旦 a1 和 x1 接触,我就会数一下,然后可以移动到 a2,依此类推。

但是,计数器没有正确更新。关于如何解决这个问题的任何建议?这是我的代码。我期望的结果显示在代码下方。

编辑

为了阐明预期结果,我更新了示例,将第二个值添加到 x。所以已经从x = [[10], [14]]更新到x = [[10, 11], [14, 12]]

以下更新。

x = [[10, 11], [14, 12]]
a = [[9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16]]

def touch(e, f):
    e = np.array(e)
    f = np.array(f)
    count = []
    counter = 0
    for i, lst in enumerate(e):
        if np.all(f > lst): # This is the condition
            counter += 0 # Counts violations of the condition
            count.append(counter)
            if i == 1:
                counter = 0
        else:
            counter += 1 # Counts violations of the condition
            print(counter)
            count.append(counter)
            if i == 1:
                counter = 0
    return count

touching = touch(x, a)
print(touching)

我期望的结果是这样的:

[2, 6]

但我明白了:

[1, 2]

编辑

为了澄清预期结果[2, 6]:我正在比较ax 中的每个列表,a 中的第 1 项与x 中的第 1 项,a 中的第 2 项到 @ 中的第 2 项987654338@.

所以:a1_1 (9)(即a 的列表 1 中的项目 1)低于 x1_1 (10)。 a1_2 (10) 等于 x1_2 (10) - 这意味着有 2 次违反条件。 a3_1 (11) > x1_1 (10) 和 a3_2 (12) > x1_2 (11) 以及 a 中的其他列表也高于其对应的元素。对于 x2(x 中的第二个列表):,a 中的所有列表都较低,除了 a7,其中 a7_1 (15) 高于 x2_1,a7_2 高于 x2_2。因此[2, 6]

【问题讨论】:

  • 为什么结果会是[2, 6]
  • 您能否解释一下您是如何从输入数据中得出预期结果的?
  • 不应该是[5,1]的结果吗?
  • 我希望[2, 6] 因为a 中的列表中的任何元素都不能小于或等于x 中的元素。与x2 相比,只有a 中的最后一个列表满足该条件。
  • 那么“找出a中有多少个列表的所有值都大于x中的对应项”应该更正。

标签: python numpy for-loop enumerate


【解决方案1】:

我不能完全按照您在代码中的推理,但您可以在单个列表理解中检查 a 和 x:

x = [[10], [14]]
a = [[9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16]]

def touch(x, a):
    return [[ all([asel > xel[0] for asel in ael]) for ael in a].count(False) for xel in x]
touching = touch(x, a)
print(touching)

>>> [2,6]

根据您的实际需要,您可以将 > 条件更改为 >= 或计算 FalseTrue 值。如果 x 的内部列表包含多个元素而不是示例中给出的一个,则还需要循环内部列表:

x = [[10, 11], [14, 12]]
a = [[9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16]]

def touch(x, a):
    return [[all([asel > xsubel for xsubel in xel for asel in ael]) for ael in a].count(False) for xel in x ]
touching = touch(x, a)
print(touching)

【讨论】:

  • 如果x 中的列表也有多个元素怎么办?例如如果x = [[10, 12], [14, 13]].
  • 那么您还必须在 x 中循环内部列表。查看更新的答案。
  • 太棒了!我不明白的是,当您向a 添加一个列表时,说``` [17, 18]```,计数器保持不变。虽然我希望它会更新。
  • 当然是一样的:你又添加了一个算作 True 的列表。尝试添加 [7,8],或尝试计算 True 而不是 False。
  • 是的,当然 - 你是对的。我的错。非常感谢。多么惊人的列表理解。我不知道他们会这么复杂。非常感谢。
【解决方案2】:

您可以使用 Numpy 来避免任何 for 循环。在下面的代码中,我假设列表 x 是一维的,因为它包含的子列表似乎由 1 个元素组成。

import numpy as np
x = [10,14]
a = [[9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16]]

e = np.array(x)
f = np.array(a)
touching = (np.sum(np.any(f[...,np.newaxis] <= e, axis = 1), axis = 0))
 
print(touching)

【讨论】:

    【解决方案3】:

    这是一个简单的解决方案,不需要numpy

    x = [[10], [14]]
    a = [[9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16]]
    
    def touch(e, f):
        # We can keep only maximum element of each list
        e = [max(lst) for lst in e]
        count = [0]*len(e)
        for lst in f:
            # Even the minimum must be greater
            min_value = min(lst)
            for i in range(len(e)):
                if min_value>e[i]:
                    count[i] += 1
        return count
    
    touching = touch(x, a)
    print(touching)
    # [5, 1]
    

    【讨论】:

    • 虽然里面有这么多的复杂性,而且看起来不像是 Python 的
    【解决方案4】:

    我有不同的看法。在python中,你可以看到:

    >>> [1, 1] > [1, 2]
    False
    >>> [1, 1] > [1, 1]
    False
    >>> [1, 1] > [1, 0]
    True
    >>> [2, 3] > [3, 3]
    False
    >>> [2, 3] < [3, 3]
    True
    >>> [2, 2] > [0, 2]
    True
    

    所以,我们可以比较整个列表。首先将x 展平,然后将xa 中的元素进行比较

    x = [[10], [14]]
    a = [[9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16]]
    
    def touch(e, f):
        e = [q for p in e for q in p] # [10, 14]
        return sum([1 for sub_list in f if sub_list > e])
    
    print(touch(x, a))
    

    【讨论】:

      猜你喜欢
      • 2015-08-03
      • 1970-01-01
      • 2013-02-20
      • 2011-01-07
      • 2021-08-24
      • 2015-12-06
      • 1970-01-01
      • 2019-06-26
      相关资源
      最近更新 更多