python – Create list of single item repeated N times

python – Create list of single item repeated N times

You can also write:

[e] * n

You should note that if e is for example an empty list you get a list with n references to the same list, not n independent empty lists.

Performance testing

At first glance it seems that repeat is the fastest way to create a list with n identical elements:

>>> timeit.timeit(itertools.repeat(0, 10), import itertools, number = 1000000)
0.37095273281943264
>>> timeit.timeit([0] * 10, import itertools, number = 1000000)
0.5577236771712819

But wait – its not a fair test…

>>> itertools.repeat(0, 10)
repeat(0, 10)  # Not a list!!!

The function itertools.repeat doesnt actually create the list, it just creates an object that can be used to create a list if you wish! Lets try that again, but converting to a list:

>>> timeit.timeit(list(itertools.repeat(0, 10)), import itertools, number = 1000000)
1.7508119747063233

So if you want a list, use [e] * n. If you want to generate the elements lazily, use repeat.

>>> [5] * 4
[5, 5, 5, 5]

Be careful when the item being repeated is a list. The list will not be cloned: all the elements will refer to the same list!

>>> x=[5]
>>> y=[x] * 4
>>> y
[[5], [5], [5], [5]]
>>> y[0][0] = 6
>>> y
[[6], [6], [6], [6]]

python – Create list of single item repeated N times

Create List of Single Item Repeated n Times in Python

Depending on your use-case, you want to use different techniques with different semantics.

Multiply a list for Immutable items

For immutable items, like None, bools, ints, floats, strings, tuples, or frozensets, you can do it like this:

[e] * 4

Note that this is usually only used with immutable items (strings, tuples, frozensets, ) in the list, because they all point to the same item in the same place in memory. I use this frequently when I have to build a table with a schema of all strings, so that I dont have to give a highly redundant one to one mapping.

schema = [string] * len(columns)

Multiply the list where we want the same item repeated

Multiplying a list gives us the same elements over and over. The need for this is rare:

[iter(iterable)] * 4

This is sometimes used to map an iterable into a list of lists:

>>> iterable = range(12)
>>> a_list = [iter(iterable)] * 4
>>> [[next(l) for l in a_list] for i in range(3)]
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]

We can see that a_list contains the same range iterator four times:

>>> a_list
[<range_iterator object at 0x7fde73a5da20>, <range_iterator object at 0x7fde73a5da20>, <range_iterator object at 0x7fde73a5da20>, <range_iterator object at 0x7fde73a5da20>]

Mutable items

Ive used Python for a long time now, and I have seen very few use-cases where I would do the above with mutable objects.

Instead, to get, say, a mutable empty list, set, or dict, you should do something like this:

list_of_lists = [[] for _ in columns]

The underscore is simply a throwaway variable name in this context.

If you only have the number, that would be:

list_of_lists = [[] for _ in range(4)]

The _ is not really special, but your coding environment style checker will probably complain if you dont intend to use the variable and use any other name.


Caveats for using the immutable method with mutable items:

Beware doing this with mutable objects, when you change one of them, they all change because theyre all the same object:

foo = [[]] * 4
foo[0].append(x)

foo now returns:

[[x], [x], [x], [x]]

But with immutable objects, you can make it work because you change the reference, not the object:

>>> l = [0] * 4
>>> l[0] += 1
>>> l
[1, 0, 0, 0]

>>> l = [frozenset()] * 4
>>> l[0] |= set(abc)
>>> l
[frozenset([a, c, b]), frozenset([]), frozenset([]), frozenset([])]

But again, mutable objects are no good for this, because in-place operations change the object, not the reference:

l = [set()] * 4
>>> l[0] |= set(abc)    
>>> l
[set([a, c, b]), set([a, c, b]), set([a, c, b]), set([a, c, b])]

Leave a Reply

Your email address will not be published.