A clean way to conditionally select items from two lists?

I have two lists:

a = [-1, 2, 3]
b = ['a', 'b', 'c']

The number of elements in aand is balways the same.

I want all the elements in to abe positive, and the corresponding elements b.

One easy way:

anew = []
bnew = []
for i in xrange(len(a)):
    if a[i] > 0:
         anew.append(a[i])
         bnew.append(b[i])

or something like

tmp = zip(*[(a[i], b[i]) for i in xrange(len(a)) if a[i]>0])
a = tmp[0] # The original a and b need not to be kept.
b = tmp[1]

I wonder if there is a shorter and cleaner (without any temporary variables) way to do this. Some type of in-place deletion would be ideal, but if I use del a[i], b[i]in a loop, the index will be erroneous after deleting one element.

EDIT: what if the selection includes two lists, for example if the condition becomes

if a[i] > 0 and b[i] > 0?

Maybe in this case you need to use a temporary variable?

+4
6

, :

filter(lambda x:x[0]>0, zip(a,b))
+2

numpy, :

In [117]: a = np.array([-1, 2, 3])
     ...: b = np.array(['a', 'b', 'c'])

In [119]: a[a>0]
Out[119]: array([2, 3])

In [120]: b[a>0]
Out[120]: 
array(['b', 'c'], 
      dtype='|S1')

numpy, :

In [121]: a = [-1, 2, 3]
     ...: b = ['a', 'b', 'c']

In [122]: print [i for i in a if i>0]
[2, 3]

In [124]: print [v for i, v in enumerate(b) if a[i]>0]
['b', 'c']
+6

"zip-filter-unzip":

:

>>> [(aa, bb) for aa, bb in zip(a, b) if aa > 0]
[(2, 'b'), (3, 'c')]
>>> zip(*[(aa, bb) for aa, bb in zip(a, b) if aa > 0])
[(2, 3), ('b', 'c')]

:

>>> aaa, bbb = zip(*[(aa, bb) for aa, bb in zip(a, b) if aa > 0])
>>> aaa
(2, 3)
>>> bbb
('b', 'c')

, - . , , : -)

, 0:

aaa, bbb = zip(*[(aa, bb) for aa, bb in zip(a,b) if aa > 0 and bb > 0])
+1

. "", .

b = [b[i] for i in xrange(len(b)) if a[i] > 0]
a = [x for x in a if x > 0]
0

.:

anew, bnew = map(lambda x: list(x), zip(*filter(lambda z: z[0] > 0, zip(a, b))))
0

, , . .

l = len(a)
i = 0
while i < l:
    print i,l
    while a[i] < 0:
        a[i] = a[-1]
        b[i] = b[-1]
        a.pop()
        b.pop()
        global l
        l = len(a)
    i = i+1


print a
print b
0
source

Source: https://habr.com/ru/post/1530363/


All Articles