As tudent
As tudent

Reputation: 71

How to duplicate a specific value in a list/array?

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.

Upvotes: 7

Views: 2084

Answers (9)

U13-Forward
U13-Forward

Reputation: 71570

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]

Upvotes: 0

William
William

Reputation: 81

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)

Upvotes: 1

colidyre
colidyre

Reputation: 4666

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

Upvotes: 0

cs95
cs95

Reputation: 402323

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])

Upvotes: 4

Denziloe
Denziloe

Reputation: 8131

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))

Upvotes: 0

Denziloe
Denziloe

Reputation: 8131

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.

Upvotes: 0

wim
wim

Reputation: 362547

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]

Upvotes: 1

niraj
niraj

Reputation: 18208

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]

Upvotes: 3

that_noob
that_noob

Reputation: 36

  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

Upvotes: 0

Related Questions