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]

5 Answers 5

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)

Sign up to request clarification or add additional context in comments.

3 Comments

Could you explain this for the.. less pythonic inclined people like me? I was thinking 2 for loops lol
@SterlingArcher, sure. In a way, I am using two for loops. I just crammed both of them into one expression.
Thanks. But as Sterling Archer told .... is there any simple logic to do this? Although, this works.
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]

Comments

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

Comments

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

1 Comment

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.
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)), [])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.