Fill a list or tuple from a callable or lambda in python

This is a problem that I have encountered recently. Google doesn't seem to have an answer, so I bring it to good people from.

I am looking for an easy way to populate a list with function output. Something like that:

fill(random.random(), 3) #=> [0.04095623, 0.39761869, 0.46227642] 

Here are other ways I've found to do this. But I am not very pleased with them, as they seem ineffective.

 results = [] for x in xrange(3): results.append(random.random()) #results => [0.04095623, 0.39761869, 0.46227642] 

and

 map(lambda x: random.random(), [None] * 3) #=> [0.04095623, 0.39761869, 0.46227642] 

Suggestions?


Thanks for all the answers. I knew there was another python-esque way.

And to efficiency issues ...

 $ python --version Python 2.7.1+ $ python -m timeit "import random" "map(lambda x: random.random(), [None] * 3)" 1000000 loops, best of 3: 1.65 usec per loop $ python -m timeit "import random" "results = []" "for x in xrange(3): results.append(random.random())" 1000000 loops, best of 3: 1.41 usec per loop $ python -m timeit "import random" "[random.random() for x in xrange(3)]" 1000000 loops, best of 3: 1.09 usec per loop 
+4
source share
5 answers

How about a list comprehension

 [random.random() for x in xrange(3)] 

In addition, in many cases, you only need values ​​once. In these cases, an expression that calculates the values ​​exactly on time and does not require memory allocation is preferable .

 results = (random.random() for x in xrange(3)) for r in results: ... # results is "used up" now. # We could have used results_list = list(results) to convert the generator 

By the way, in Python 3.x, xrange been replaced by range . In Python 2.x, range allocates memory and computes all values ​​in advance (for example, list comprehension), while xrange calculates values ​​on time and does not allocate memory (this is a generator).

+10
source

why do you think they are ineffective?

There is another way to do this, understanding the list

 listt= [random.random() for i in range(3)] 
+2
source
  list = [random.random() for i in xrange(3)] list = [random.random() for i in [0]*3] list = [i() for i in [random.random]*3] 

Or:

  fill =lambda f,n: [f() for i in xrange(n)] fill(random.random , 3 ) #=> [0.04095623, 0.39761869, 0.46227642] 
0
source

something more general ...

 from random import random fill = lambda func, num: [func() for x in xrange(num)] # for generating tuples: fill = lambda func, num: (func() for x in xrange(num)) # then just call: fill(random, 4) # or... fill(lambda : 1+2*random(), 4) 
0
source

Understanding the list is probably the clearest, but for itertools afficionado:

 >>> list(itertools.islice(iter(random.random, None), 3)) [0.42565379345946064, 0.41754360645917354, 0.797286438646947] 

A quick check with timeit shows that the itertools version is so slightly faster for more than 10 elements, but still comes with what seems most clear to you:

 C:\Python32>python lib\timeit.py -s "import random, itertools" "list(itertools.islice(iter(random.random, None), 10))" 100000 loops, best of 3: 2.93 usec per loop C:\Python32>python lib\timeit.py -s "import random, itertools" "[random.random() for _ in range(10)]" 100000 loops, best of 3: 3.19 usec per loop 
0
source

Source: https://habr.com/ru/post/1388970/


All Articles