简体   繁体   English

如何根据python中的另一个列表删除列表中的元素,没有循环?

[英]How to remove elements in a list based on another list in python, without loops?

I have two lists of equal length: 我有两个相等长度的列表:

list_a = ['a','b','c','d']
list_b = [-6.3, 3.1, 0.5, 4.1]

I want to remove the elements < 0.7 in list_b, and simultaneously remove the corresponding elements from list_a, ie 我想删除list_b中的元素<0.7,同时从list_a中删除相应的元素,即

list_a_2 = ['b','d']
list_b_2 = [3.1, 4.1]

I know the second list, 我知道第二个清单,

list_b_2 = [item for item in hem if item > 0.7]. 

But is there a list-thinking way to get list_a_2, without using loops? 但有没有一个列表思维方式来获取list_a_2,而不使用循环?

One way is to use zip : 一种方法是使用zip

list_a_2, list_b_2 = zip(*[(a, b) for a, b in zip(list_a, list_b) if b > 0.7])    
list_a_2
# ('b', 'd')

list_b_2
# (3.1, 4.1)

If a for loop is better suited, you can create two empty lists and conditionally append the values to them: 如果for循环更适合,您可以创建两个空列表并有条件地将值附加到它们:

list_a_2, list_b_2 = [], []
for a, b in zip(list_a, list_b):
    if b > 0.7:
        list_a_2.append(a)
        list_b_2.append(b)

list_a_2
# ['b', 'd']

list_b_2
# [3.1, 4.1]

Without explicit loops, create both? 没有显式循环,创建两个? Sure, if we use a temporary object: 当然,如果我们使用临时对象:

list_a = ['a','b','c','d']
list_b = [-6.3, 3.1, 0.5, 4.1]
tmp = zip(a, b)
list_a_2 = [x[0] for x in tmp if x[1] > 0.7]
list_b_2 = [x[1] for x in tmp if x[1] > 0.7]
del tmp

But using an actual for-loop will be a bit more obvious: 但是使用实际的for循环会更明显一些:

for idx, value in enumerate(list_b):
    if value =< 0.7:
        list_a.pop(idx)
        list_b.pop(idx)

But you're still managing two lists for mapping (basically) keys to values. 但是你仍在管理两个列表,用于将键(基本上)映射到值。 This is what a dictionary is for! 这就是字典的用途! Consolidate those list and create your subset with some dictionary comprehension: 合并这些列表并使用一些字典理解创建您的子集:

{x:y for x, y in zip(list_a, list_b) if y > 0.7}

If you really want to avoid loops you can use a recursive function: 如果你真的想避免循环,你可以使用递归函数:

def unnecessarily_recursive_function(list_a,list_b):
    try:
        a = list_a.pop(0)
        b = list_b.pop(0)
        tmp_a, tmp_b = unnecessarily_recursive_function(list_a,list_b)
        if b < 0.7:
            return [a] + tmp_a, [b] + tmp_b
        else:
            return tmp_a, tmp_b
    except IndexError:
        return [],[]

which you can call like: 您可以这样称呼:

list_a, list_b = unnecessarily_recursive_function(list_a, list_b)

Note that this is a really bad reason to use a recursive function and you should definitely actually go with the other suggestions above. 请注意,这是使用递归函数的一个非常糟糕的理由,你肯定应该使用上面的其他建议。

Thanks a lot! 非常感谢! For other people having a same problem: 对于有同样问题的其他人:

I end up with the following code: 我最终得到以下代码:

list_a = ['a','b','c','d']
list_b = [-6.3, 3.1, 0.5, 4.1]
tmp = zip(a, b)
list_a_2 = [x[0] for x in tmp if x[1] > 0.7]
list_b_2 = [x[1] for x in tmp if x[1] > 0.7]
del tmp

And a better idea might be directly use a dataframe to match each element with its own label. 更好的想法可能是直接使用数据框来匹配每个元素与自己的标签。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM