13

I have one array like A = [1,2,3] and another array B = [4,5,6]. Now, I need another array C so that the elements in C should be the same elements of B having occurrence in the order of element A. Like, C = [4, 5, 5, 6, 6, 6]

ZdaR
  • 19,186
  • 6
  • 55
  • 76
sparrow
  • 227
  • 1
  • 4
  • 14

5 Answers5

17
A = [1,2,3]
B = [4,5,6]
C = [b_item for a_item, b_item in zip(A,B) for _ in range(a_item)]
print C

Result:

[4, 5, 5, 6, 6, 6]

This is a one-line equivalent to:

C = []
for a_item, b_item in zip(A,B):
    for _ in range(a_item):
        C.append(b_item)

... Which is roughly equivalent to

C = []
for i in range(min(len(A), len(B))):
    a_item = A[i]
    b_item = B[i]
    for _ in range(a_item):
        C.append(b_item)

(N.B. Don't get tripped up by the underscore. It's an ordinary variable. It is conventionally used when you don't actually have to refer to the variable's value, as in this example)

Community
  • 1
  • 1
Kevin
  • 69,817
  • 12
  • 97
  • 139
  • 1
    Could you explain this for the.. less pythonic inclined people like me? I was thinking 2 for loops lol – Sterling Archer May 20 '15 at 19:03
  • @SterlingArcher, sure. In a way, I _am_ using two for loops. I just crammed both of them into one expression. – Kevin May 20 '15 at 19:09
  • Thanks. But as Sterling Archer told .... is there any simple logic to do this? Although, this works. – sparrow May 20 '15 at 19:11
6

I will provide another way of doing it, using a different idea (not claiming he should use this, but for didactic reasons)

I find pretty neat to be able to replicate elements in python using

[0]*3 # it means we create 3 elements of zero: [0,0,0]

if I simply do this:

[[x]*i for i,x in zip(A, B)] 

I get groups of elements:

[[4], [5, 5], [6, 6, 6]]

Then, we could use itertools.chain to get back to a single list:

from itertools import chain
list(chain(*[[x]*i for i,x in zip(A, B)]))
[4, 5, 5, 6, 6, 6]
Sam Felix
  • 1,279
  • 1
  • 10
  • 22
5

Here's another solution using numpy:

import numpy

a = numpy.array = [1,2,3]
b = numpy.array = [4,5,6]

c = numpy.repeat(b,a)

Result:

array([4, 5, 5, 6, 6, 6])

Here more information about using numpy.repeat : http://docs.scipy.org/doc/numpy/reference/generated/numpy.repeat.html

mugabits
  • 955
  • 1
  • 11
  • 22
2

My solution:

C = sum([[B[i]]*A[i] for i in range(len(A))], [])
print C

Explaination:

[B[i]]*A[i] will create a list with A[i] items of B[i]

[B[i]]*A[i] for i in range(len(A))] will give you a list of lists, eg [[4], [5, 5], [6, 6, 6]]

sum(C, []) will convert list of lists into list

Tuan Anh Hoang-Vu
  • 1,888
  • 1
  • 21
  • 31
  • 1
    Yep, this works. `sum(sequence, [])` is a little inefficient memory-wise since it has to create multiple intermediary lists, but that's not a big deal if C is reasonably small. – Kevin May 20 '15 at 19:14
1

Another way:

C = []
for a, b in zip(A, B):
    C.extend([b] * a)

But I'd prefer the list comprehension, just without the annoying _item, i.e.,

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

Or the shorter (but for large cases slow) sum:

C = sum(([b] * a for a, b in zip(A, B)), [])
Stefan Pochmann
  • 24,379
  • 7
  • 36
  • 92