[Tutor] all right students, what do we learn

Alan Gauld alan.gauld at btinternet.com
Sun Nov 2 10:03:57 CET 2014

On 02/11/14 05:43, Clayton Kirkwood wrote:

> So I head down the path of all sorts of variations of the following. And
> I mean all sorts. Instead of [reenter, key_columns] I used a single
> list. Instead of the exec(‘reenter = True’) I used a simple reenter=True
> (and an eval and compile which I don’t totally understand yet).

Don't use exec, eval or compile. Consider them for experts
only and hardly ever needed.

They are extremely dangerous and doubly so if you don't know
exactly what you are doing. You could, for example, wind up accidentally 
deleting your files or formatting your hard disk.

> out that python doesn’t seem to like an assignment in the overall if
> clause – error.

Correct, the if statement requires an expression (specifically a boolean 
expression). And assignments are not expressions.

> Weird thing, entering   a y   would make the final
> print spit out (False, 'a') (False, 'o') but the entry of  hhh   caused
> the final print to spit out []

Why do you think that weird? Its exactly what I'd expect. You don't have 
a key 'hhh' in the data you showed us.

Remember that the comprehension is trying to build a list containing 
only those output expressions that match the if clause. If the if
fails then nothing gets put in the output.

> Which I don’t quite understand. The reason is because I set up the if
> statement to be True either way. With an   a   it would go thru and
> create the proper output.

Can you explain in English what you want the output to be?
The reason I ask is that you seem to be creating a list of
pairs where the first element is the result of the 'in' test and the 
second is the value. Do you really want that or do you just want the 
ones that match either true or false?

If you really want the result/value pair then a better way
to write your comprehension is to use the in test in the
output, like so:

result = [(key in key_list0, key) for key in key_list]

That doesn't print any error messages but the end list should be
the same as the one you produced.

> reenter=True
> while reenter:
>      reenter=False
>      key_list = input('Please enter space separated keys in the order
> you want: ').split()
>      [reenter, key_columns ]=[(reenter, key) for key in key_list if
> ((key in key_list0)) or (print("Error:", key, "not available, start
> again") and exec('reenter = True', ))]
>      print(reenter,key_columns)

My translation of the above into English is:

"Keep asking the user for keys until they hit upon a list
that is all valid and create a list of corresponding values."

Is that correct?

If so I'd write it like this:

prompt = 'Please enter space separated keys in the order you want: '
while True:  # keep going round till we break
    key_list = input(prompt).split()
    if all(key in key_list0 for key in key_list):

result = [(key, key_columns) for key in key_list]

However, there is a bit of inconsistency with your data - for example 
where does key_columns come from? It's going to be the same value for 
each key. So the last line might be better as:

result = [pair for pair in key_list0 if pair[0] in key_list]

Which would give you a list containing each user key and its 
corresponding value from key_list0.

Is that something like what you want?

Alan G
Author of the Learn to Program web site

More information about the Tutor mailing list