39

Does Python have something like below?

for item in items #where item>3:
  #.....

I mean Python 2.7 and Python 3.3 both together.

Alan Coromano
  • 24,958
  • 53
  • 135
  • 205

5 Answers5

69

You can combine the loop with a generator expression:

for x in (y for y in items if y > 10):
    ....

itertools.ifilter (py2) / filter (py3) is another option:

items = [1,2,3,4,5,6,7,8]

odd = lambda x: x % 2 > 0

for x in filter(odd, items):
    print(x)
georg
  • 211,518
  • 52
  • 313
  • 390
  • 7
    This is the right way to do it as no intermediate array is produced. This is called a generator expression. IMO its a pity you cant just write the shorter `for x in items if x>10:` though. – Michael Anderson Oct 20 '12 at 09:23
  • @MichaelAnderson: yeah, that would be neat. This syntax is said to have been rejected by Guido, I haven't found a proof though. – georg Oct 20 '12 at 09:41
  • @georg could you please elaborate in what would be the `itertools.ifilter` usage? – Sebastián Vansteenkiste Aug 31 '18 at 15:54
  • Oh! I didn't realize you meant the `filter` function, yes, that's more comftible for writing some things. I should probably start paying attention to performance, so far I've settled for making generator expressions as readable as possible, but I until I sit down and measure with clocks I probably won't know if my solutions are "good enough" – Sebastián Vansteenkiste Sep 03 '18 at 14:56
12

You mean something like this: -

item_list = [item for item in items if item > 3]

Or, you can use Generator expression, that will not create a new list, rather returns a generator, which then returns the next element on each iteration using yield method: -

for item in (item for item in items if item > 3):
    # Do your task
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
5

There isn't a special syntax like the where in your question, but you could always just use an if statement within your for loop, like you would in any other language:

for item in items:
    if item > 3:
        # Your logic here

or a guard clause (again, like any other language):

for item in items:
    if not (item > 3): continue

    # Your logic here

Both of these boring approaches are almost as succinct and readable as a special syntax for this would be.

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
  • The top-rated solution with a generator expression is more functional and indicates exactly what the list contains on the line of the for expression. – Neil Apr 17 '14 at 18:13
3

Python 3 and Python 2.7 both have filter() function which allows extracting items out of a list for which a function (in the example below, that's lambda function) returns True:

>>> nums=[1,2,3,4,5,6,7,8]
>>> for item in filter(lambda x: x>5,nums):
...     print(item)
... 
6
7
8

Omitting function in filter() will extract only items that are True, as stated in pydoc filter

Sergiy Kolodyazhnyy
  • 938
  • 1
  • 13
  • 41
2

You could use an explicit if statement:

for item in items:
    if item > 3:
       # ...

Or you could create a generator if you need a name to iterate later, example:

filtered_items = (n for n in items if n > 3)

Or you could pass it to a function:

total = sum(n for n in items if n > 3)

It might be matter of taste but I find a for-loop combined with inlined genexpr such as for x in (y for y in items if y > 3): to be ugly compared to the above options.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670