通过示例进行说明可能更容易。
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]
给予
C = [3]
但是对于如何继续此处并没有一个明确的想法。
答案 0 :(得分:2)
您可以使用以下方法:
>>> 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]
之所以可行,是因为当您将list
的{{1}}转换为tuple
时,重复的密钥会被最后一个密钥覆盖。
答案 1 :(得分:1)
如果您想要一支班轮,那么这可行,假设我的评论是正确的解释:
[min([B[j] for j in [ind for ind,x in enumerate(A) if x==y]]) for y in A]
要进行分解,请对A
中的索引和值进行最内层的列表理解,然后再次对A
中的所有值进行下一个列表理解(将它们存储在{{ 1}}),并用作前面提到的列表的条件。
然后,您可以使用该索引列表来获取y
中的所有元素(使用B
)并最终获得该列表上的j
。
enumerate将索引和值分别返回到min
和ind
中。
答案 2 :(得分:1)
如果您不介意使用名为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]
答案 3 :(得分:0)
是的,可以在一行中。
[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]