0
this = rand(100,3,4)
for i in range(0,100):
    for j in range(0,3):
        for k in range(0,4):
            if rand()<0.5:
                this[i,j,k]=0

Where rand is numpy.random.rand

Can the above be written in chained list comprehension?

Aim: to assign value 0 to each term in "this" (3D matrix) with certain probability(0.5)

Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
  • 1
    The output is not a list, so not sure why you are asking for a list comprehension? Are you asking is there a more pythonic way to refactor your nested for loops? – Burhan Khalid Jun 02 '15 at 04:49
  • @Burhan : yes. Can the same thing be done using a chained list comprehension? Without nested loops? – Abhishek Tripathi Jun 02 '15 at 05:01
  • The result of a list comprehension is a _list_; your code is not generating a list (it is instead modifying the matrix) so not sure why you are looking for a list comprehension. – Burhan Khalid Jun 02 '15 at 05:11
  • matrix can be thought of as lists in list, right? But I am more comfortable with your solution. Just that comprehensions run faster. That's why I was into list comprehension. using `numpy.where` should be fast enough. :) – Abhishek Tripathi Jun 02 '15 at 05:14
  • I should have been more explicit - a list comprehension expression evaluates to a _new list_; it is not designed for modifying lists in-place (you should avoid doing that anyway - its a great source of bugs). `numpy.where` would probably be faster if not equivalent to a comprehension - noting that you would be building a list, and then discarding it if you were to implement your loop as a comprehension. – Burhan Khalid Jun 02 '15 at 05:28
  • OKay. Thanks a lot. Made my day. :) – Abhishek Tripathi Jun 02 '15 at 09:45

1 Answers1

3

It seems to me that you're better off using builtin numpy routines such as numpy.where...

>>> import numpy
>>> import numpy.random
>>> x = numpy.random.rand(100, 3, 4)
>>> mask = numpy.random.rand(*x.shape)
>>> result = numpy.where(mask < 0.5, 0, x)
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
mgilson
  • 300,191
  • 65
  • 633
  • 696