使这一点更简单,因为/if块更具pythonic

使这一点更简单,因为/if块更具pythonic,python,Python,我需要将超过给定最大限制的3个列表中的值的索引存储在一个列表中。这就是我得到的: # Data lists. a = [3,4,5,12,6,8,78,5,6] b = [6,4,1,2,8,784,43,6,2] c = [8,4,32,6,1,7,2,9,23] # Maximum limit. max_limit = 20. # Store indexes in list. indexes = [] for i, a_elem in enumerate(a): if a_ele

我需要将超过给定最大限制的3个列表中的值的索引存储在一个列表中。这就是我得到的:

# Data lists.
a = [3,4,5,12,6,8,78,5,6]
b = [6,4,1,2,8,784,43,6,2]
c = [8,4,32,6,1,7,2,9,23]

# Maximum limit.
max_limit = 20.

# Store indexes in list.
indexes = []
for i, a_elem in enumerate(a):
    if a_elem > max_limit or b[i] > max_limit or c[i] > max_limit:
        indexes.append(i)
这很管用,但我觉得很难看。我怎样才能让它更优雅/更像蟒蛇?

你可以试试

if max(a_elem, b[i], c[i]) > max_limit:
    indexes.append(i)
这里的逻辑是找出这三个值中的任何一个是否需要大于max_limit。如果这三个元素中的最大元素大于最大限制,则满足您的条件。

您可以尝试

if max(a_elem, b[i], c[i]) > max_limit:
    indexes.append(i)
m = lambda l: [i for i, e in enumerate(l) if e>max_limit]
indexes = sorted(set(m(a) + m(b) + m(c)))

这里的逻辑是找出这三个值中的任何一个是否需要大于max_limit。如果这三个循环中的最大元素大于max_limit,则满足条件。

您可以将
for
循环替换为:

m = lambda l: [i for i, e in enumerate(l) if e>max_limit]
indexes = sorted(set(m(a) + m(b) + m(c)))
indexes = []
for i, triplet in enumerate(zip(a, b, c)):
    if any(e > max_limit for e in triplet):
        indexes.append(i)
。。。您可以将其简化为一个列表:

indexes = [i for i, t in enumerate(zip(a, b, c)) if any(e > max_limit for e in t)]
。。。虽然这对我来说似乎有点笨拙——这确实是关于个人品味,但我更喜欢保持列表简单;在我看来,for循环的三行
更清晰

正如用户2357112所指出的,使用
max()
,可以降低列表理解的明显复杂性:


。。。虽然这不会像
any()
版本(以及您自己的代码)那样短路,但可能会稍微慢一点。

您可以将
for
循环替换为:

indexes = []
for i, triplet in enumerate(zip(a, b, c)):
    if any(e > max_limit for e in triplet):
        indexes.append(i)
>>> maximums = map(max, zip(a, b, c))
>>> [i for i, num in enumerate(maximums) if num > max_limit]
[2, 5, 6, 8]
。。。您可以将其简化为一个列表:

indexes = [i for i, t in enumerate(zip(a, b, c)) if any(e > max_limit for e in t)]
。。。虽然这对我来说似乎有点笨拙——这确实是关于个人品味,但我更喜欢保持列表简单;在我看来,for
循环的三行
更清晰

正如用户2357112所指出的,使用
max()
,可以降低列表理解的明显复杂性:

。。。虽然这不会像
any()
版本(以及您自己的代码)那样短路,但可能会稍微慢一点

>>> maximums = map(max, zip(a, b, c))
>>> [i for i, num in enumerate(maximums) if num > max_limit]
[2, 5, 6, 8]
旧答案

之前,我把这些乱七八糟的东西贴在下面。上面的列表比较容易管理

>>> next(zip(*filter(lambda i: i[1] > max_limit, enumerate(map(max, zip(a, b, c))))))
(2, 5, 6, 8)
旧答案

之前,我把这些乱七八糟的东西贴在下面。上面的列表比较容易管理

>>> next(zip(*filter(lambda i: i[1] > max_limit, enumerate(map(max, zip(a, b, c))))))
(2, 5, 6, 8)

我自己最喜欢
exceders=

import collections

# Data lists.
a = [3,4,5,12,6,8,78,5,6]
b = [6,4,1,2,8,784,43,6,2]
c = [8,4,32,6,1,7,2,9,23]

Triad = collections.namedtuple('Triad', 'a b c')
triads = [Triad(*args) for args in zip(a, b, c)]

triads = [t for t in zip(a, b, c)]  # if you don't need namedtuple

# Maximum limit.
max_limit = 20.

# Store indexes in list.
indexes = [for i, t in enumerate(triads) if max(t) > max_limit]
print indexes

# store the bad triads themselves in a list for
# greater pythonic

exceeders = [t for t in triads if max(t) > max_limit]
print exceeder
正如我在上面所评论的,使用并行数组来表示相关的数据会使简单的代码比需要的简单得多

在回复评论时添加

也许我给了你太多的选择,所以我只能给你一种选择。所有答案的一个共同特点是,它们使用zip将单独的“数据列表”融合成行:

triads = [t for t in zip(a, b, c)]
exceeders = [t for t in triads if max(t) > max_limit]
就是这样:两行。重要的一点是,在列表中存储任何内容的索引是一种C风格的处理方式,而您要求的是一种Python方式。保留索引列表意味着,无论何时,只要您想对该索引处的数据执行某些操作,就必须执行间接寻址。执行这两行后,
超出者
的值为:

[(5, 1, 32), (8, 784, 7), (78, 43, 2), (6, 2, 23)]
其中,列表中的每个成员都有三个数据行的“列”,这些数据行被发现超出了您的限制


现在你可能会说“但我真的想要指数”。如果是这样的话,你的问题还有另一部分没有告诉我们,它也依赖于列表索引。如果是这样的话,你仍然在用C/C++/Java的方式做事情,而“Pythonic”仍然是回避的。

我自己最喜欢
exceders=

import collections

# Data lists.
a = [3,4,5,12,6,8,78,5,6]
b = [6,4,1,2,8,784,43,6,2]
c = [8,4,32,6,1,7,2,9,23]

Triad = collections.namedtuple('Triad', 'a b c')
triads = [Triad(*args) for args in zip(a, b, c)]

triads = [t for t in zip(a, b, c)]  # if you don't need namedtuple

# Maximum limit.
max_limit = 20.

# Store indexes in list.
indexes = [for i, t in enumerate(triads) if max(t) > max_limit]
print indexes

# store the bad triads themselves in a list for
# greater pythonic

exceeders = [t for t in triads if max(t) > max_limit]
print exceeder
正如我在上面所评论的,使用并行数组来表示相关的数据会使简单的代码比需要的简单得多

在回复评论时添加

也许我给了你太多的选择,所以我只能给你一种选择。所有答案的一个共同特点是,它们使用zip将单独的“数据列表”融合成行:

triads = [t for t in zip(a, b, c)]
exceeders = [t for t in triads if max(t) > max_limit]
就是这样:两行。重要的一点是,在列表中存储任何内容的索引是一种C风格的处理方式,而您要求的是一种Python方式。保留索引列表意味着,无论何时,只要您想对该索引处的数据执行某些操作,就必须执行间接寻址。执行这两行后,
超出者
的值为:

[(5, 1, 32), (8, 784, 7), (78, 43, 2), (6, 2, 23)]
其中,列表中的每个成员都有三个数据行的“列”,这些数据行被发现超出了您的限制


现在你可能会说“但我真的想要指数”。如果是这样的话,你的问题还有另一部分没有告诉我们,它也依赖于列表索引。如果是这样的话,您仍在以C/C++/Java的方式进行操作,“Pythonic”将继续回避。

使用
max(triplet)>max_limit
any
更简单,并将列表理解简化为更易于理解的形式。@user2357112 True(以额外计算为代价-
any()
短路方式与OP的
解决方案相同)。将添加一个完整的
max()
版本…使用
max(triplet)>max\u limit
any
更简单,并将列表理解简化为更易于理解的形式。@user2357112 True(以额外计算为代价-
any()
以OP的
解决方案相同的方式短路)。将添加一个完整的
max()。也许a会使数据更符合您的使用。很大一部分丑陋来自于在并行列表中隐藏(a[i],b[i],c[i])的相关性。也许a会使数据更符合您的使用。我相信这肯定有很多好处,但我发现它非常复杂。@Gabriel,请参阅上面的“添加”部分,其中我为您降低了巨大的复杂性。我肯定这肯定有很多好处,但我发现它非常复杂。@Gabriel,请参阅“添加”在上面,我为您减少了巨大的复杂性。