在尝试锻炼列表理解时,我遇到了重复所需的值。
我有2个列表:L1,L2。需要的结果是L2中的项目列表,如果这些项目小于/等于,则至少有一个项目在L1中。
L1=[10,20,30,40,50]
L2=[3,11,51]
L3=[d2 for d2 in L2 for d1 in l1 if d2<=d1]
L3返回为[3,3,3,3,3,11,11,11,11]
答案包含有效的项目,但会重复。 我知道使用set(),我们可以摆脱重复,但可能是我以错误的方式使用列表理解。任何澄清将不胜感激。
实现预期结果的循环是:
L3=[]
for d2 in L2:
for d1 in L1:
if d2<=d1:
L3.append(d2)
答案 0 :(得分:5)
从扩展到循环可以看出,内部循环遍历L1
中的每个元素,因此d2
元素将在每时间附加一次L2
中更大的元素。
您可以使用set()
(等同于HepaKKes建议的{ }
括号)来摆脱重复,但效率很低 - 您仍然在创建不需要的中间结果。这将是O(n^2)
时间。
您选择的项目是<=
,而不是L1
中的任何项目。这与询问它们是否为<= max(L1)
是一样的。以下是:
L3 = [e for e in L2 if e < max(L1)]
将达到相同的效果。如果您提前保存L1
的值
L1_max = max(L1)
L3 = [e for e in L2 if e < L1_max]
然后此解决方案为O(n)
。
答案 1 :(得分:2)
你写的内容经历了两个嵌套的for循环,只要条件d2<=d1
为真,就会附加该值。因此,我们看到为{em>每个值添加了3
和11
,这些值在L2中小于。
相反,您需要更严格的条件才能将d2
添加到L3
,这样您的理解就可以是L3 = [d2 for d2 in L2 if (x)]
形式,其中x
相当于“d2
小于L1
”中的某个值。有几种方法可以做到这一点,但我发现以下工作:
L3 = [d2 for d2 in L2 if (filter(lambda d1: d2<=d1, L1))]
答案 2 :(得分:1)
如果任务是写一个列表理解,我会选择这样的东西:
In [22]: [x for x in L2 if any([y >= x for y in L1])]
Out[22]: [3, 11]