7

Any advice on how to repeat a certain value in an array in Python? For instance, I want to repeat only 2 in array_a:

array_a = [1, 2, 1, 2, 1, 1, 2]

Wanted outcome is: I repeat each 2 and leave the 1:

array_a = [1, 2, 2, 1, 2, 2, 1, 1, 2, 2]  # only the `2` should be repeated

I tried numpy and I could duplicate the entire array but not a certain value.

2
  • 1
    I recommend that you choose a tutorial on list manipulation that fits your current learning level. There are many ways to do this, but the way you ask questions suggests that you would benefit from a wider presentation of the topic. Tutorial-level education is beyond the range of Stack Overflow. Commented Sep 14, 2018 at 0:05
  • Added the numpy tag since OP has used numpy to attempt a solution. Commented Sep 14, 2018 at 0:41

9 Answers 9

4

If you're interested in a numpy solution, you can repeat an array on itself using np.repeat.

>>> import numpy as np
>>> np.repeat(array_a, array_a)
array([1, 2, 2, 1, 2, 2, 1, 1, 2, 2])

This works only if you haves 1s and 2s in your data. For a generic solution, consider

>>> n_repeats = 2
>>> temp = np.where(np.array(array_a) == 2, n_repeats, 1)
>>> np.repeat(array_a, temp)
array([1, 2, 2, 1, 2, 2, 1, 1, 2, 2])
Sign up to request clarification or add additional context in comments.

1 Comment

amazing! as usual
3

May be you can use dictionary to each unique element and number of times it needs to be repeated. Then using list comprehension to create array:

array_a = [1,2,1,2,1,1,2]

repeat_times = {1:1, 2:2} # 1 is 1 time and 2 is repeated two times

result = [i for i in array_a for j in range(repeat_times[i])]
print(result) 

Output:

[1, 2, 2, 1, 2, 2, 1, 1, 2, 2]

1 Comment

Nice approach. Style tip: use _ for dummy variables like j.
1

This seems a good use-case for a generator:

>>> def repeater(iterable, repeat_map):
...     for value in iterable:
...         for i in range(repeat_map.get(value, 1)):
...             yield value
...             
>>> array_a = [1,2,1,2,1,1,2]
>>> list(repeater(array_a, repeat_map={2: 2}))
[1, 2, 2, 1, 2, 2, 1, 1, 2, 2]

Comments

1

If you convert this to a list, you can loop through it, and if it matches your criteria, add an extra version. For example:

a = [1,2,1,2,1,1,2]
long_a = []
for x in a:
    long_a.append(x)
    if x == 2:
       long_a.append(x)

1 Comment

Nice solution -- the call to list is unnecessary though.
0
  1. loop over the array (a 'list' in python)

  2. find the the number

  3. get the position of the matched number in the array

  4. insert another number after each matched position

https://docs.python.org/3/reference/compound_stmts.html#for

https://docs.python.org/2/tutorial/datastructures.html#more-on-lists

1 Comment

wouldn't this override the number after a matched position? should i increase array size then shift then add element?
0

An attempt using comprehensions.

array = [1, 2, 1, 2, 1, 1, 2]

element_to_repeat = 2

result = [
    repeats_element
    for repeats in
        ((element,)*2 if element == element_to_repeat else (element,) for element in array)
    for repeats_element in repeats
]

It basically spits out tuples, "repeats", which contain the element once if it's not the element to repeat, or twice if it's the element to repeat. Then all of the elements of these "repeats" tuples are flattened into the answer.

1 Comment

Bizarre downvote, it's the same as an upvoted answer.
0

Using a generator.

array = [1, 2, 1, 2, 1, 1, 2]

element_to_repeat = 2

def add_repeats(array, element_to_repeat):
    for element in array:
        if element == element_to_repeat:
            yield element
            yield element
        else:
            yield element

result = list(add_repeats(array, element_to_repeat))

Comments

0

Here is a handy one-liner using itertools and list comprehension with if and else in it. First it makes a nested list (to have the ability to repeat items on a certain position) and then it will simply flatten it at the end using .chain()-method:

from itertools import chain
array_a = [1, 2, 1, 2, 1, 1, 2]

list(chain.from_iterable([[item, item] if item == 2 else [item] for item in array_a]))
[1, 2, 2, 1, 2, 2, 1, 1, 2, 2]  # output

The specific value to double is inside the if-statement. Using multipliers (instead of [item, item]) and a variable (instead of 2) would make this easily more generic, see this for example:

from itertools import chain

def repeat_certain_value(array, val, n):
    return list(chain.from_iterable(([i] * n if i == val else [i] for i in array)))

repeat_certain_value([1, 2, 1, 2, 1, 1, 2], 2, 2)
[1, 2, 2, 1, 2, 2, 1, 1, 2, 2]  # output

repeat_certain_value([0, -3, 1], -3, 5)
[0, -3, -3, -3, -3, -3, 1]  # output

While this approach is a handy one-liner using builtin libraries, the approach from coldspeed is faster:

%timeit for x in range(1000): repeat_certain_value([1, 1, 1, 2, 2, 2, 3, 3, 3] * 100, 2, 2)
10 loops, best of 3: 165 ms per loop

%timeit for x in range(1000): coldspeeds_solution([1, 1, 1, 2, 2, 2, 3, 3, 3] * 100, 2, 2)
10 loops, best of 3: 100 ms per loop

Comments

0

Can try a list comprehension and create a flat function:

array_a = [1, 2, 1, 2, 1, 1, 2]
def flat(l):
   newl=[]
   for i in l:
      if isinstance(i,list):
         newl.extend(i)
      else:
         newl.append(i)
   return newl
print(flat([[i]*2 if i==2 else i for i in array_a]))

Output:

[1, 2, 2, 1, 2, 2, 1, 1, 2, 2]

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.