2

I want to have a one-liner code using list comprehension which prints this sequence for an arbitrary n:

[1, 1, 2, 2, 3, 3, 4, 4, 5, 5, ..., n, n]
accdias
  • 5,160
  • 3
  • 19
  • 31
d_b
  • 185
  • 1
  • 2
  • 13

3 Answers3

2

Let's try this:

n = 10
result = [i//2 + 1 for i in range(n*2)]
print(result)

This code uses list comprehension: the range(n*2) function generates a range of numbers from 0 to n*2-1 and i//2 + 1 gives the index of the pair of numbers that contains the current number, i.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
2
[e for l in [[x]*2 for x in range(1, 10)] for e in l]
[1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9]

Could be read as follows : element for each list in list of list as we know list of list is [[x]*2 for x in range(1, 10)]

>>> [[x]*2 for x in range(1, 10)]
[[1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9]]

In definitive, another way to flatten a 2-levels list in one line without using for instance tools like numpy.ndarray.flatten or numpy.ravel

Modified by Accdias (reduction of for loops and then time consumption) :

[n for i in range(1, 10) for n in [i] * 2]

Indeed excellent, because uses the property of created elements which are lists and then could be iterated in the run process :

  • creation of the list-like little unit [i] * 2
  • iteration over the creation with the nearest for loop
  • and flatten process ends with the last for loop
Laurent B.
  • 1,653
  • 1
  • 7
  • 16
  • Based on OP expected result, this seems the simplest and best solution. It can be improved as `[n for i in range(1, 10) for a in [i] * 2]` or even `[n for i in range(1, 10) for a in (i, i)]`. – accdias Feb 24 '23 at 05:21
  • Thanks for sharing, but the two propositions will each generate an exception. fact is ```n``` is not defined by the way your lists comps are written. – Laurent B. Feb 24 '23 at 07:15
  • 1
    That was clearly a typo. Here is what I meant them to be: `[n for i in range(1, 10) for n in [i] * 2]` and `[n for i in range(1, 10) for n in (i, i)]`. – accdias Feb 25 '23 at 00:35
1

If need append new column to existing DataFrame:

Use numpy.repeat with numpy.arange with filtering for assign even or odd number of rows:

df = pd.DataFrame({'a': range(4)})

n = df.shape[0]
df['new'] = np.repeat(np.arange(1, n // 2 + 2), 2)[:n]
print (df)
     a  new
0    0    1
1    1    1
2    2    2
3    3    2

df = pd.DataFrame({'a': range(5)})

n = df.shape[0]
df['new'] = np.repeat(np.arange(1, n // 2 + 2), 2)[:n]
print (df)
   a  new
0  0    1
1  1    1
2  2    2
3  3    2
4  4    3

If always even number of rows, solution is:

df = pd.DataFrame({'a': range(8)})

df['new'] = np.repeat(np.arange(1, df.shape[0] // 2 + 1), 2) 
print (df)
   a  new
0  0    1
1  1    1
2  2    2
3  3    2
4  4    3
5  5    3
6  6    4
7  7    4
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252