Python 使用列表理解根据使用其他列表的条件替换重复项
用一个例子来说明可能更容易Python 使用列表理解根据使用其他列表的条件替换重复项,python,list-comprehension,Python,List Comprehension,用一个例子来说明可能更容易 A = [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3] B = [0.1, 0.2, 0.3, 0.4, 0.01, 0.02, 0.03, 0.04, 0.001, 0.001, 0.0003, 0.0003] 我有上面的两张清单 A中的每个元素都会重复几次。每个元素的多重性可以不同(并且它们不必像这里那样排序) B包含与A相同数量的元素。我想将A中每个重复元素中的最小元素分配给列表C(其中最小值来自B列表中的相应值。因此,对于前4个元素
A = [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]
B = [0.1, 0.2, 0.3, 0.4, 0.01, 0.02, 0.03, 0.04, 0.001, 0.001, 0.0003, 0.0003]
我有上面的两张清单
A中的每个元素都会重复几次。每个元素的多重性可以不同(并且它们不必像这里那样排序)
B包含与A相同数量的元素。我想将A中每个重复元素中的最小元素分配给列表C(其中最小值来自B列表中的相应值。因此,对于前4个元素,它将是0.1,对于接下来的4个元素,它在本例中是0.01,对于最后4个元素,它是0.0003的重复值,并且对于每个重复元素都是如此)
我想获得以下列表
C = [0.1, 0.1, 0.1, 0.1, 0.01, 0.01, 0.01, 0.01, 0.0003, 0.0003, 0.0003, 0.0003]
由于我正在使用的代码已经广泛使用列表理解,所以我希望使用相同的方法
这可能吗
这样做明智吗
我熟悉一些简单的情况,比如
C = A[B < 0.0005]
但是,对于如何在此处继续操作,您还没有明确的想法。您可以使用以下方法:
>>> A = [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]
>>> B = [0.1, 0.2, 0.3, 0.4, 0.01, 0.02, 0.03, 0.04, 0.001, 0.001, 0.0003, 0.0003]
>>> AB = zip(A, B)
>>> AB_sorted = sorted(AB, key=lambda i: (i[0], -i[1]))
>>> AB_dict = dict(AB_sorted)
>>> C = [AB_dict[i] for i in A]
>>> C
[0.1, 0.1, 0.1, 0.1, 0.01, 0.01, 0.01, 0.01, 0.0003, 0.0003, 0.0003, 0.0003]
这是因为当您将
元组的列表
转换为dict
时,重复的键会被最后一个键覆盖。如果您想要一行,这是有效的,假设我的注释是正确的解释:
[min([B[j] for j in [ind for ind,x in enumerate(A) if x==y]]) for y in A]
要分解它,最里面的列表理解将遍历A
中的索引和值,然后下一个列表理解将再次遍历A
中的所有值(将它们存储在y
),并用作前面提到的列表的条件。
然后使用此索引列表获取B
(使用j
)中的所有元素,最后获取该列表中的min
enumerate将索引和值分别返回到ind
和x
。如果您不介意使用名为Pandas
的附加Python库,可以执行以下操作:
import pandas as pd
A = [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]
B = [0.1, 0.2, 0.3, 0.4, 0.01, 0.02, 0.03, 0.04, 0.001, 0.001, 0.0003, 0.0003]
df = pd.DataFrame([A, B]).T.rename(columns={0: 'A', 1: 'B'})
req_dict = {key: value for key, value in df.groupby('A')['B'].min().iteritems()}
print(df['A'].replace(req_dict))
输出:
[0.1, 0.1, 0.1, 0.1, 0.01, 0.01, 0.01, 0.01, 0.0003, 0.0003, 0.0003, 0.0003]
是的,一行就可以了
[min(y for x, y in zip(A, B) if z == x) for z in A]
这将生成此列表
[0.1, 0.1, 0.1, 0.1, 0.01, 0.01, 0.01, 0.01, 0.0003, 0.0003, 0.0003, 0.0003]
当你说最小的元素时,你是指最低的索引吗?如果是,我建议你根据最小的值来编辑这个问题。因此,对于前4个元素,它将是0.1
,对于接下来的4个元素,在本例中它是0.01
,对于最后4个元素,它是0.0003
的重复值,你的意思是如果重复项在索引x、y、z、w(在A
中)中,因此您需要min(B[[x、y、z、w]])
?工作起来很有魅力。列表理解令人惊讶……非常感谢!我还有其他一些类似的条件需要解决,但我认为这会帮助我自己解决。是的,有时需要很多测试,但如果你一步一步地做,打印出结果列表,并增加复杂性,我发现这会让它更易于管理确实如此。目前,我设法访问了每个最小值的索引。C=[B.index(min([B[j]表示j in[ind for ind,x in enumerate(A)if x==y]]))表示y in A]
这不是OP所寻找的列表。
[0.1, 0.1, 0.1, 0.1, 0.01, 0.01, 0.01, 0.01, 0.0003, 0.0003, 0.0003, 0.0003]