Reputation: 29
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, i.e.
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?
Upvotes: 2
Views: 88
Reputation: 29
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.
Upvotes: 0
Reputation: 214927
One way is to use 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:
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]
Upvotes: 6
Reputation: 5213
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.
Upvotes: 0
Reputation: 1283
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 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}
Upvotes: 1