I want to create a list consisting of, for example, twenty items. Each element must be an arbitrary integer from -10 to 10.

  from random import randint

 numbers = []
 for i in range (20):
     numbers.append (randint (-10, 10)) 

Or so

 from random import randint
 lst = [randint (-10, 10) for i in range (20)]

How to do the same thing, just to have it on one line (except for imports) (for example, using a list inclusion, a generator expression, some functions from map (), zip (), functions from itertools) and there was no intermediate variable (i)?

    3 answers 3

    import timeit, random, itertools, operator, functools, numpy a, b, s = -10, 10, 1000 v1=lambda: list(numpy.random.randint(a, b, s)) v2=lambda: [random.randint(a, b) for _ in range(s)] v3=lambda: list(map(lambda _: random.randint(a, b), range(s))) v4=lambda: list(itertools.starmap(lambda: random.randint(a, b), [()]*s)) v5=lambda: list(r(a, b) for r in [random.randint]*s) v6=lambda: [r() for r in [functools.partial(random.randint, a, b)]*s] v7=lambda: list(operator.methodcaller('__call__', a, b)(r) for r in [random.randint]*s) v8=lambda: list(map(operator.methodcaller('__call__', a, b), [random.randint]*s)) v9=lambda: list(map(operator.methodcaller('__call__'), [functools.partial(random.randint, a, b)]*s)) v10=lambda: numpy.random.randint(a, b, s).tolist() def execTime(target_: list, repeat=1): for n, fn in target_: print(n, timeit.Timer(fn).timeit(1), fn()) target_[:] = [(n, timeit.Timer(fn).timeit(repeat)) for n, fn in target_] for e, (n, tmt) in enumerate(sorted(target_, key=lambda r: r[1]), start=1): print("{}'time {} {}".format(e, n, tmt)) if __name__ == '__main__': target = [(n, fn) for n, fn in sorted(globals().items()) if n.startswith('v')] execTime(target, repeat=100) 

    out:

     v1 0.00013895335493526386 [8, 6, 8,..] ... v9 0.0034144395633564986 [-8, 3, -3,..] 1'time v10 0.005898359039140072 2'time v1 0.014917592744244368 3'time v5 0.32350102439781625 4'time v2 0.33059889747340865 5'time v4 0.3355538953844154 6'time v8 0.34316236373969566 7'time v3 0.3506998448115352 8'time v6 0.3632192647513499 9'time v9 0.3795784125105248 10'time v7 0.4123779585340184 
    • Thank you, I learned a lot of new things! - pynix
    • 3
      @pynix map() does not return the list in Python 3. For portability, it is better to use the [randint(-10, 10) for _ in range(20)] option given in the question. If you want, post it as your answer (replace i with _). The use of underscores is an accepted convention for such cases in Python. - jfs
    • I understood what vadim vaduxa meant. On the other hand, indeed, it is actually the same thing that I wrote, with the exception of the replaced designation of the variable i by _. But since I learned that this designation is generally accepted for such cases, I was no longer tormented by the use of the "parasitic" variable. I will use it in the future. - pynix
    • NumPy has a built-in method for converting an array to a list - array.tolist() . Try to replace: list(numpy.random.randint(a, b, s)) -> numpy.random.randint(a, b, s).tolist() - should be 1.5–2 times faster for such k- WA Elements ... - MaxU September
    • really thank you - vadim vaduxa

    You can use NumPy:

     import numpy as np lst = np.random.randint(-10, 10, 20) print(lst) 

    You can easily create matrices:

     In [3]: np.random.randint(-10, 10, (5,3)) Out[3]: array([[-10, 2, 8], [ -8, -3, 8], [ -1, 8, 8], [ 8, 9, -7], [ 4, 5, -4]]) 

      Suitable if you want to create a sample without repeating.

       from random import sample list = sample(range(-10, 11), 20) 
      • and sample (range (-10, 11), 1000) is no longer working - vadim vaduxa
      • @vadimvaduxa thank you for your attention. My answer is not correct for the question. - Roxio0