python in-line for loops - python

I'm wondering if there is a way in python to use a simplified, in-line for loop to do different things.
For example:
for x in range(5):
print(x)
to be written in a simpler form, such as
print (x) for x in range(5)
but this does not seem to be working.
I've been googling for finding the right syntax for a couple hours without success. The only alternative I found is, when the in-line for loop is used to access elements of a list:
print ([x for x in range(5)])
is working, but it is doing something else, than what I'm looking for.
Can someone point to the right syntax or let me know if there are any restrictions? (maybe in-line for loops work only about lists?)

Quick answer:
There is no such a thing as "in line for loops" in python
A trick that works:
in python 3.*:
[print(x) for x in range(5)]
Because print is a function
In python 2.* printis not a function but you could define myprint and use it like this:
>>> def myprint(x):
... print x
...
>>> _=[ myprint(x) for x in range(5)]
0
1
2
3
4
More in depth:
What you call "in-line for loops" or "shortforms" are actually list comprehensions and (quoting documentation)
provide a concise way to create lists
The first part of a list comprehension (before the forkeyword) must contain an expression used to create list values. If your expression contains a function that has the (side) effect of printing something it works... but it is exactly a side effect. What you are really doing is creating a list and then discarding it.
Note that you can't assign values (like q += (x * y)) in a list comprehension because assignments are not expressions.

You can join your items with new line character and print it.But this is not a proper way for just printing I recommend the your first code using a simple loop.
>>> print '\n'.join([str(x) for x in range(5)])
0
1
2
3
4
Or since map performs better at dealing with built-in functions rather than list comprehension you can use map(str, range(5))
The result would be your first code :
>>> for x in range(5):
... print(x)
...
0
1
2
3
4
You can also do it in one line :
>>> for x in range(5):print(x)
...
0
1
2
3
4

Related

what's the difference between filter and comprehention with if?

def anagramwordchecker(z,w):
if sorted([x for x in w])==sorted([x for x in z]):return True
return False
def anagramlistchecker(l,w):
d={}
for x in w:
d.update({x:w.count(x)})
l=list(filter(lambda x:anagramwordchecker(x,w),l))
return l
print(anagramlistchecker(['bcda', 'abce', 'cbda', 'cbea', 'adcb'],'abcd'))
trying to check which words are anagram.
using both of this it will print the same:
l=[x for x in l if anagramwordchecker(x,w)]
l=list(filter(lambda x:anagramwordchecker(x,w),l))
and it will be:
['bcda', 'cbda', 'adcb']
then what's the difference? any advantage using filter? cause comprehension is easier.
If you print the results of the following example, you will know which one is faster (Comments are results I got).
timeit.Timer('''[x for x in range(100) if x % 2 == 0]''' ).timeit(number=100000)
timeit.Timer('''list(filter(lambda x: x % 2 == 0, range(100)))''').timeit(number=100000)
# 0.3664856200000486
# 0.6642515319999802
So in your case, list comprehension would be faster. But let's see the following example.
timeit.Timer('''[x for x in range(100) if x % 2 == 0]''' ).timeit(number=100000)
timeit.Timer('''(x for x in range(100) if x % 2 == 0)''' ).timeit(number=100000)
timeit.Timer('''filter(lambda x: x % 2 == 0, range(100))''').timeit(number=100000)
# 0.5541256509999357
# 0.024836917000016
# 0.017953075000036733
The results show that casting an iterable to list takes much time and filter is faster than generator expression. So if your result does not really have to be a list, returning an iterable in a timely manner would be better.
As stated in here,
Note that filter(function, iterable) is equivalent to the generator expression (item for item in iterable if function(item)) if function is not None and (item for item in iterable if item) if function is None.
But list comprehension can do much more than simply filtering. If filter is given to the interpreter, it will knows it is a filter function. However, if a list comprehension is given to the interpreter, the interpreter does not know what it really is. After taking some time interpreting the list comprehension to something like a function, it would be a filter or filterfalse function in the end. Or, something else completely different.
filter with not condition can do what filterfalse does. But filterfalse is still there. Why? not operator does not need to be applied.
There is no magic. Human-friendly 1-for-many grammars are based on encapsulation. For them to be machine-executable binaries, they need to be decapsulated back and it takes time.
Go with a specific solution if it is enough than taking a more general solutions. Not only in coding, general solutions are usually for convenience, not for best results.

Is defining a variable using a for loop possible in Python?

If I'd want to do for i in range(10): x+= 1 it obviously wouldn't work since x is undefined, I'd have to declare x e.g. x=0 before trying to write to it, but now I have two lines, one for declaring x=0 and one for actually writing the data I want to x (for i in range(10): x+= 1).
I was wondering, is there a way to do this in a single line? Or more specifically, declaring x as the result of a for loop?
Something along the lines of x = for i in range(10): x+= 1 ?
Would this even be possible or am I asking a nonsense question?
Not with a for statement.
However, you can use a similar construct, such as a list comprehension expression or a generator expression:
x = sum(i for i in range(10))
which is equivalent to just saying
x = sum(range(10))
Edit: as Dougal correctly notes, in your example you increment by 1, so the equivalent is
x = sum(1 for i in range(10))
which is in turn the same as x = len(range(10)) or just x = 10.
In most cases, i would imagine you would just want to use x as the loop variable:
for x in range(10): pass#or range(1,11)
An enumerate would also achieve a similar effect as what you are describing, assuming you want a different variable as the loop variable so as to do something else in the loop:
e.g.
for i,x in enumerate(range(x_start,x_end+1)):
#do something

How to create a function that uses 2 integers from 2 different lists and adding the pair to a certain integer?

Doing some basic python coding. Here is the problem I was presented.
Create a function that takes 3 inputs:
Two lists of integers
one integer n
Prints the pairs of integers, one from the first input list and the other form the second list, that adds up to n. Each pair should be printed.
Final Result (Example):
pair([2,3,4], [5,7,9,12], 9)
2 7
4 5
I'm still awfully new to Python, studying for a test and for some reason this one keeps giving me some trouble. This is an intro course so basic coding is preferred. I probably won't understand most advanced coding.
The simplest naieve approach would be to just test all possible combinations to see if they add up.
def pair(list1, list2, x):
for a in list1:
for b in list2:
if a + b == x:
print a, b
There are more efficient ways to do it (eg. ignore duplicates, ignore numbers greater than x, etc.)
If you wanted to do it in a single loop, python has some convenience functions for that
from itertools import product
for a, b in product(list1, list2):
if a + b == x:
print a, b

Change Loop to Python List Comprehension

There is a list of objects, "games." How can I check to see if the object has an attribute set, and if it doesn't, set the attribute.... using list comprehensions?
for g in games:
if not g.score_ratio_h1: g.score_ratio_h1 = avg_score_ratio_h1
This is not a good case for using list comprehensions, in fact: it's very anti-Pythonic. The loop doesn't result in the creation of a new list of values, it's just a sequence of assignments. Better stick to using a loop, it's fine as it is. Only if your code looked like this:
ans = []
for g in games:
if not g.score_ratio_h1:
ans.append(g.score_ratio_h1) # we're appending the results
... Then it'd be a good idea to use comprehensions. But currently the core of the loop is an assignment:
g.score_ratio_h1 = avg_score_ratio_h1
And no useful value returns of that, it's a modification operation (a "side effect") that doesn't get collected anywhere. Comprehensions are not meant to be used in such cases. Even more: trying to do an assignment inside a comprehension will result in an error, for example:
lst = [[0], [0], [0]]
[a[0] = 1 for a in lst]
^
SyntaxError: invalid syntax
well you can do something like this that uses list comprehension:
for g in (g for g in games if not g.score_ratio_h1):
g.score_ratio_h1 = avg_score_ratio_h1
it may be perhaps a bit faster... but strange :)
EDIT:
I agree with the two comments, however it may not be completely wasteful depending on the "if" condition, here an example:
lst = [0 for _ in xrange(708)]
for i in xrange(100000000):
if i**2 < 500000:
lst[i] += i
time:
real 0m12.906s
user 0m12.876s
sys 0m0.008s
versus:
lst = [0 for _ in xrange(708)]
for i in (i for i in xrange(100000000) if i**2 < 500000):
lst[i] += i
time:
real 0m8.857s
user 0m8.792s
sys 0m0.016s
I guess that depending on the condition, and the size of the loop this may be indeed wasteful, but in sometimes it may help to play around list comprehension, even in this case.

Does python have a shorthand for this simple task?

I've just started to learn the long-heard python language. I've been working with C before. And I find python, as a modern script language is much concise on various tasks.
So I was wondering, if I have a list foo = [1, 2, 3, 4, 5], and I want to pick all the odd numbers out of it into bar. In C, I might use a loop and check each number in foo and copy the elements needed into bar. What do you guys do this "python-style"?
bar = [x for x in foo if x % 2 == 1]
This form is called "list comprehension". In its basic form, it has 4 parts:
What you want to include in the output list. Can be any expression involving the variable(s) defined in the second part (below). In this case, the element x, unmodified;
A variable, or expression, denoting an element of the input list. Following the for keyword, each element of the list will be bound to that variable (if your list contains complex objects, you can use destructuring assignment to refer only to specific parts of it). In this case, each item of the list is bound to x;
The input list. Following the in keyword, the list (or other iterable) where you'll get your elements from. In this case, foo;
A condition that the element must meet to be included in the result (optional). If included, add the keyword if followed by an expression to determine whether or not that element will be included in the output list. In this case, it will be if the number is odd.
filter function is what you are looking for:
bar = filter(lambda x: x % 2 == 1, foo)
The expression lambda x: x % 2 == 1 is basically equivalent to
def isOdd(x):
return x % 2 == 1

Categories