Reputation: 2292
Why is this code:
x = {"first":(True, "first description"), "second":(False, "second description")}
items = ["first", "second"]
for element in [k in x and x[k][0] for k in items]:
print element
printing
instead of the elements in the "items"-list that match the expression
k in x and x[k][0]
Upvotes: 3
Views: 171
Reputation: 12501
Because the expression
to generate new list in [k in x and x[k][0] for k in items]
is k in x and x[k][0]
, and the evaluation of and
process is that it'll split the whole expression by and
, then evaluate each "sub-expression"
, return the first falsy
value or the last value no matter whatever it is. In this case it'll first evaluate k in x
, which will always be true
, then it will return the result of x[k][0]
, which generates the final result:
[True, False]
If you try [k in x and x[k][0] for k in items]
, you'll get result:
['first description', 'second description']
To filter element, you need to put the test condition at the tail of the whole expression like:
[k for k in items if k in x and x[k][0]]
Upvotes: 0
Reputation: 1121874
You are printing the outcome of the expression k in x and x[k][0]
.
That's either going to be False
(if the outcome of the k in x
condition is false), or the outcome of x[k][0]
(if the outcome of k in x
was true). Since x[k][0]
is a boolean object in your input sample, you'll always get boolean values here; nowhere will the list comprehension produce the keys instead.
If you wanted to filter, use an if
statement after the loop:
[k for k in items if k in x and x[k][0]]
This then produces a list with k
values for which the expression produces true, which for your sample data matches just one element, ['first']
, because only for that key is the first element in the tuple set to True
.
Upvotes: 4
Reputation: 1216
x = {"first":(True, "first description"), "second":(False, "second description")}
items = ["first", "second"]
for element in [k in x and x[k][0] for k in items]:
print element
Lets try to understand what result it gives you from the list comprehension.
[k in x and x[k][0] for k in items]
Lets observe it from the right side. for k in items == ['first', 'second']
1st iteration
k = 'first'
['first' in x (True) and x['first'][0] (True)]
[True and True]
[True]
2nd Iteration
k = 'second'
list is [True]
[True, 'second' in x (True) and x['second'][0] (False)]
[True, True and False]
[True, False]
Now,
for element in [True, False]:
print element
It should print,
True
False
which is what it is doing.
Upvotes: 2
Reputation: 27283
[k in x and x[k][0] for k in items]
returns the boolean expression k in x and x[k][0]
for every element in items
, which will be True for every element whose first element is truthy.
What you probably mean is:
[k for k in items if k in x and x[k][0]]
Upvotes: 3