Make one list of two constraints applying the list

I have two lists A, B

A = [2,3,1,4,5,2,4]
B = [4,2,3,6,2,5,1]

      

I want to combine these A and B as:

C = [2,4,2,3,1,3,4,6,2,5,2,5,1,4]

      

regulations:

  • A [i] <= B [i], take A [i], then B [i]
  • A [i]> B [i], take B [i], then A [i]

I can do this using a loop like below:

C = []

for a,b in zip(A,B):
    if(a<=b):
        C.append(a)
        C.append(b)
    else:
        C.append(b)
        C.append(a)

      

It really works. How can I do it like this:

 C = [ [a,b if (a<=b)],[ b,a else] for a,b in zip(A,B)] # This is totally wrong

      

But how can I do this using if-else

+3


source to share


5 answers


The way you do it is good because it is very readable ... but if the one-liner is what you commit after me:

>>> A = [2,3,1,4,5,2,4]
>>> B = [4,2,3,6,2,5,1]
>>> [i for sublist in [[a, b] if a < b else [b, a] for a, b in zip(A, B)] for i in sublist]
[2, 4, 2, 3, 1, 3, 4, 6, 2, 5, 2, 5, 1, 4]

      

A few notes:

  • When you add a conditional expression to the comp list, use if - else

    immediately after the first variable in the comp list.['a' if i in (2, 4, 16) else 'b' for i in [1, 2, 3, 16, 24]]

  • The best way to build (mentally) nested lists is to think about how you would write it in a normal loop.




C = [[a, b] if a < b else [b, a] for a, b in zip(A, B)]
for sublist in C:
    for i in sublist:
        yield i

      

Then you just flatten the nested loops and bring them yield i

to the front, discarding yield

.

for sublist in C for i in sublist yield i
|-> yield i for sublist in C for i in sublist
    |-> i for sublist in C for i in sublist

      

Now you can just replace C with the comp list above and get the one-liner I posted.

+5


source


Use itertools.chain.from_iterable

,

import itertools 
A = [2,3,1,4,5,2,4]
B = [4,2,3,6,2,5,1]  
list(itertools.chain.from_iterable(i if i[0]<=i[1] else (i[1], i[0]) for i in zip(A, B)))

      

or collect tuple

. You get by running two listszip(A, B)



list(itertools.chain.from_iterable(sorted(i) for i in zip(A, B)))

      

See. Time difference, using List Comprehension

, map

,sorted

In [70]: %timeit list(itertools.chain.from_iterable(i if i[0]<=i[1] else (i[1], i[0]) for i in zip(A, B)))
100000 loops, best of 3: 3.49 Β΅s per loop

In [71]: %timeit list(itertools.chain.from_iterable(sorted(i) for i in zip(A, B)))
100000 loops, best of 3: 5.81 Β΅s per loop

In [72]: %timeit [i for sublist in [[a, b] if a < b else [b, a] for a, b in zip(A, B)] for i in sublist]
100000 loops, best of 3: 3.28 Β΅s per loop

In [73]: %timeit list(itertools.chain.from_iterable(map(lambda x:x[1]>x[0] and (x[0],x[1]) or (x[1],x[0]),zip(A,B))))
100000 loops, best of 3: 4.26 Β΅s per loop

      

+1


source


Or something like this?

C = sum([[a,b] if a <= b else [b, a] for (a,b) in zip(A,B)], [])

      

+1


source


>>> list(itertools.chain.from_iterable(map(lambda x:x[1]>x[0] and (x[0],x[1]) or (x[1],x[0]),zip(A,B))))
[2, 4, 2, 3, 1, 3, 4, 6, 2, 5, 2, 5, 1, 4]

      

0


source


You can do

C = [sorted([a, b]) for a, b in zip(A, B)]

      

and combine all C elements.

-1


source







All Articles