This question already has answers here:
if/else in a list comprehension
(12 answers)
Is it possible to use 'else' in a list comprehension? [duplicate]
(6 answers)
Closed 3 years ago.
I'm just getting started with Python and was reading about list comprehensions.
The following code:
my_list = [x ** x for x in range(1,11) if x % 2 == 0]
print(my_list)
... produces this output:
[4, 256, 46656, 16777216, 10000000000]
I then tried this code:
my_list = [x ** x for x in range(1,11) if x % 2 == 0 else 7]
print(my_list)
... but I got a syntax error starting at the second "e" in else.
Can someone explain why I'm getting a syntax error? I'd like to have the list create a list of even squares based on the value of the base (x), and to have the value "49" if the list value is not an "even number" square.
In this case, you would want
my_list = [x ** x if x % 2 == 0 else 49 for x in range(1,11)]
If you use an if at the end of a list comprehension like that, it is used to select which elements to include. If you want a different result depending on the case, you need to use a ternary if at the beginning instead.
For more info, take a look at the docs here. To quote:
A list comprehension consists of brackets containing an expression followed by a for clause, then zero or more for or if clauses. The result will be a new list resulting from evaluating the expression in the context of the for and if clauses which follow it.
There is no support for else here, presumably because a ternary if (if condition then foo else bar) in the 'body' of the comprehension already accomplishes this and "There should be one-- and preferably only one --obvious way to do it."
Related
This question already has answers here:
What does the "yield" keyword do in Python?
(51 answers)
Why does the print function return None?
(1 answer)
Closed 2 years ago.
I have tried this following code:
result = (x for x in range(3))
for y in result:
print(y)
I am getting the following Output:
0
1
2
But when I am using this code :
result = (print(x) for x in range(3))
for y in result:
print(y)
I am getting the following output:
0
None
1
None
2
None
Can anyone explain, Why this None is coming in output in second code?
Because print(x) prints the value of x (which is the digits that get printed) and also returns None (which is the Nones that get printed)
print doesn't return a value, so you are seeing None, which is the return for print, and the output from print. This is a classic case of using comprehension syntax for side effects, which is not using the generator/comprehension syntax to contain an actual result. You can check this by running:
print(print('x'))
x
None
This question already has answers here:
How to test if one string is a subsequence of another?
(4 answers)
Python list filtering: remove subsets from list of lists
(10 answers)
Closed 4 years ago.
I know many similar questions has been asked before with answers but my concern is related to builtin functionality rather than my own logic of loops and indexes etc.
In my python app, I need to check if listA is subset of listB. I've done this with the help of sets like this
set(listA) < set(listB)
It works fine overall but I also need to check order of objects in list. e.g.
x = ['a','b','c','d']
xx = ['a', 'c']
xxx = ['c' , 'a']
so according to sets definition;
set(xx) < set(x) returns true and set(xxx) < set(x) also returns true...
But I need something that returns false for 2nd case.
Is there any builtin functionality in python or I need to implement my own logic to get required result?
I think a better word for this operation is a subsequence.
You need to write this yourself, but you can do it fairly easily by walking both lists together:
def is_subsequence(a, b):
b_it = iter(b)
try:
for a_val in a:
while next(b_it) != a_val:
pass
except StopIteration:
return False
else:
return True
used as:
>>> is_subsequence(xx, x)
True
>>> is_subsequence(xxx, x)
False
Edit: Searching for "subsequence" finds this great answer.
This question already has answers here:
Test if lists share any items in python
(9 answers)
Closed 4 years ago.
I have two lists, for example:
a = ["mail1", "mail2", "mail3", "mail4"]
b = ["mail2", "mail5"]
and I want to check if any of the elements in list b also appears in list a.
I wanted to know if there is a way (and what is it) to do this without a for loop.
Also I wanted to know how can I create a list of boolean values, where each value will be the result of the comparison of values a[i] and b[i], something like:
[z for i, j in zip(a, b) z = i == j] # (just with the right syntax)
z will be 1 if in some place i == j, so I can check the array for any 'True' values.
You can use any:
any(x in a for x in b)
The nice thing about this generator expression is that any will return True as soon as the generator yields a True, i.e. there won't be redundant x in a lookups.
Edit:
You can improve the time complexity by making a set from a.
a_set = set(a)
any(x in a_set for x in b)
Regarding your new question:
[x == y for x,y in zip(a,b)]
Elegant way is to use sets:
a = ["mail1", "mail2", "mail3", "mail4"]
b = ["mail2", "mail5"]
anb = set(a) & set(b)
print anb
if anb:
print True
>>> set(['mail2'])
>>> True
The any function takes in an iterable (See documentation here), so the answer should be any([x in a for x in b])
This question already has answers here:
python operator precedence of in and comparison [duplicate]
(3 answers)
Closed 9 years ago.
Consider this list:
list = [1,2,3,4,5]
I want to check if the number 9 is not present in this list. There are 2 ways to do this.
Method 1: This method works!
if not 9 in list: print "9 is not present in list"
Method 2: This method does not work.
if 9 in list == False: print "9 is not present in list"
Can someone please explain why method 2 does not work?
This is due to comparison operator chaining. From the documentation:
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
You are assuming that the 9 in list == False expression is executed as (9 in list) == False but that is not the case.
Instead, python evaluates that as (9 in list) and (list == False) instead, and the latter part is never True.
You really want to use the not in operator, and avoid naming your variables list:
if 9 not in lst:
It should be:
if (9 in list) == False: print "9 is not present in list"
This question already has answers here:
What is the purpose of the single underscore "_" variable in Python?
(5 answers)
Closed 8 months ago.
Reading through Peter Norvig's Solving Every Sudoku Puzzle essay, I've encountered a few Python idioms that I've never seen before.
I'm aware that a function can return a tuple/list of values, in which case you can assign multiple variables to the results, such as
def f():
return 1,2
a, b = f()
But what is the meaning of each of the following?
d2, = values[s] ## values[s] is a string and at this point len(values[s]) is 1
If len(values[s]) == 1, then how is this statement different than d2 = values[s]?
Another question about using an underscore in the assignment here:
_,s = min((len(values[s]), s) for s in squares if len(values[s]) > 1)
Does the underscore have the effect of basically discarding the first value returned in the list?
d2, = values[s] is just like a,b=f(), except for unpacking 1 element tuples.
>>> T=(1,)
>>> a=T
>>> a
(1,)
>>> b,=T
>>> b
1
>>>
a is tuple, b is an integer.
_ is like any other variable name but usually it means "I don't care about this variable".
The second question: it is "value unpacking". When a function returns a tuple, you can unpack its elements.
>>> x=("v1", "v2")
>>> a,b = x
>>> print a,b
v1 v2
The _ in the Python shell also refers to the value of the last operation. Hence
>>> 1
1
>>> _
1
The commas refer to tuple unpacking. What happens is that the return value is a tuple, and so it is unpacked into the variables separated by commas, in the order of the tuple's elements.
You can use the trailing comma in a tuple like this:
>>> (2,)*2
(2, 2)
>>> (2)*2
4