3

I've declared a list of tuples that I would like to manipulate. I have a function that returns an option from the user. I would like to see if the user has entered any one of the keys 'A', 'W', 'K'. With a dictionary, I would say this: while option not in author.items() option = get_option(). How can I accomplish this with a list of tuples?

authors = [('A', "Aho"), ('W', "Weinberger"), ('K', "Kernighan")]

3 Answers 3

2
authors = [('A', "Aho"), ('W', "Weinberger"), ('K', "Kernighan")]
option = get_option()
while option not in (x[0] for x in authors):
    option = get_option()

How this works :

(x[0] for x in authors) is an generator expression, this yield the [0]th element of each item one by one from authors list, and that element is then matched against the option. As soon as match is found it short-circuits and exits.

Generator expressions yield one item at a time, so are memory efficient.

Sign up to request clarification or add additional context in comments.

4 Comments

I just initialized option = '' prior to the loop, then once inside I received option. This helped a lot, thanks!
+1 the list comp. is far nicer than the zip(*iter)[0] solution.
To get the name associated with option would I need to print authors[option]?
@Dford.py No You can't do that here, you've to do a liner search again to get the name. name = next(x[1] for x in authors if x[0] == option)
1

How about something like

option in zip(*authors)[0]

We are using zip to essentially separate the letters from the words. Nevertheless, since we are dealing with a list of tuples, we must unpack it using *:

>>> zip(*authors)
[('A', 'W', 'K'), ('Aho', 'Weinberger', 'Kernighan')]
>>> zip(*authors)[0]
('A', 'W', 'K')

Then we simply use option in to test if option is contained in zip(*authors)[0].

8 Comments

I'm a little confused on how to use this, could explain this a little more?
zip will return a list of tuples, which you can then iterate over like any other iterable. That does mean that the syntax here is a bit incomplete, though.
@Makoto I'm not sure I see what the problem is.
@Dford.py I added a little more of an explanation.
@arshajii I appreciate that, thanks a lot. if I wanted to inspect the input of option would I only need to specify it like this: if option == 'A': # then do something
|
0

There are good answers here that cover doing this operation with zip, but you don't have to do it like that - you can use an OrderedDict instead.

from collections import OrderedDict
authors = OrderedDict([('A', "Aho"), ('W', "Weinberger"), ('K', "Kernighan")])

Since it remembers its entry order, you can iterate over it without fear of getting odd or unusual orderings of your keys.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.