33

Suppose I have a given Object (a string "a", a number - let's say 0, or a list ['x','y'] )

I'd like to create list containing many copies of this object, but without using a for loop:

L = ["a", "a", ... , "a", "a"]

or

L = [0, 0, ... , 0, 0]

or

L = [['x','y'],['x','y'], ... ,['x','y'],['x','y']]

I'm especially interested in the third case. Thanks!

Deniz
  • 1,481
  • 3
  • 16
  • 21

6 Answers6

56

You can use the * operator :

L = ["a"] * 10
L = [0] * 10
L = [["x", "y"]] * 10

Be careful this create N copies of the same item, meaning that in the third case you create a list containing N references to the ["x", "y"] list ; changing L[0][0] for example will modify all other copies as well:

>>> L = [["x", "y"]] * 3
>>> L
[['x', 'y'], ['x', 'y'], ['x', 'y']]
>>> L[0][0] = "z"
[['z', 'y'], ['z', 'y'], ['z', 'y']]

In this case you might want to use a list comprehension:

L = [["x", "y"] for i in range(10)]
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Luper Rouch
  • 9,304
  • 7
  • 42
  • 56
  • 5
    +1: The * operator acting on lists is just meant to do what the original poster wanted. The list(itertools.repeat()) solution is too big a hammer for a small nail. – Eric O. Lebigot May 07 '10 at 11:40
  • You'll receive a gold bagde now, as I've upvoted it and the accepted answer, so that this answer could have **2x** votes in comparison to the accepted answer which has minimum 10 votes. Both answers are good irrespective of the gold badge, BTW. :-) – Nawaz Dec 31 '15 at 10:51
  • 3
    In the last case, since you're not using the variable `i`, I believe the polite thing to do is name it `_`, i.e. `L = [['x', 'y'] for _ in range(10)]`. – krs013 Mar 02 '17 at 18:22
  • Actually, just the last line (using the comprehension) is the correct answer, since the OP specifically asked for copies (!) of the original object. There is a similar question - https://stackoverflow.com/questions/3459098 - that asks about repeated items, and for that case the `*` operator is the correct solution. – raner Sep 30 '21 at 19:36
36

itertools.repeat() is your friend.

L = list(itertools.repeat("a", 20)) # 20 copies of "a"

L = list(itertools.repeat(10, 20))  # 20 copies of 10

L = list(itertools.repeat(['x','y'], 20)) # 20 copies of ['x','y']

Note that in the third case, since lists are referred to by reference, changing one instance of ['x','y'] in the list will change all of them, since they all refer to the same list.

To avoid referencing the same item, you can use a comprehension instead to create new objects for each list element:

L = [['x','y'] for i in range(20)]

(For Python 2.x, use xrange() instead of range() for performance.)

Amber
  • 507,862
  • 82
  • 626
  • 550
  • 9
    Using an underscore instead of `i` to indicate it's a throwaway variable is good practice IMO: `L = [['x','y'] for _ in range(20)]` – Zaz Dec 11 '15 at 00:34
2

You could do something like

x = <your object>
n = <times to be repeated>
L = [x for i in xrange(n)]

Substitute range(n) for Python 3.

John Flatness
  • 32,469
  • 5
  • 79
  • 81
0

If you want unique instances and like to golf, this is (slightly) shorter:

L = [['x', 'y'] for _ in []*10]

The crazy thing is that it's also (appreciably) faster:

>>> timeit("[['x', 'y'] for _ in [0]*1000]", number=100000)   
8.252447253966238                                             
>>> timeit("[['x', 'y'] for _ in range(1000)]", number=100000)
9.461477918957826
krs013
  • 2,799
  • 1
  • 17
  • 17
0

I hope this helps somebody. I wanted to add multiple copies of a dict into a list and came up with:

>>> myDict = { "k1" : "v1" }
>>> myNuList = [ myDict.copy() for i in range(6) ]
>>> myNuList
[{'k1': 'v3'}, {'k1': 'v3'}, {'k1': 'v3'}, {'k1': 'v3'}, {'k1': 'v3'}, {'k1': 'v3'}]
>>> myNuList[1]['k1'] = 'v4'
>>> myNuList
[{'k1': 'v3'}, {'k1': 'v4'}, {'k1': 'v3'}, {'k1': 'v3'}, {'k1': 'v3'}, {'k1': 'v3'}]

I found that:

>>> myNuList = [ myDict for i in range(6) ]

Did not make fresh copies of the dict.

  • *"Did not make fresh copies of the dict"* - that's because `myNuList = [myDict for i in range(6)]` just creates 6 references to the same `dict`. – FObersteiner Dec 18 '19 at 16:22
0

In case you want to create a list with repeating elements inserted among others, tuple unpacking comes in handy:

l = ['a', *(5*['b']), 'c']
l
Out[100]: ['a', 'b', 'b', 'b', 'b', 'b', 'c']

[the docs]

FObersteiner
  • 22,500
  • 8
  • 42
  • 72