0

In page 29 of the third edition of the Python Cookbook, the author makes the following statement:

"... might also be done by creating a sequence of tuples and passing them to the dict() function. For example:

p1 = dict((key, value) for key, value in prices.items() if value > 200)

The author's referral of the argument passed to the dict() constructor as a "sequence" kinda got me wondering... what exactly is for ... in ...? It isn't an expression is it? One can't just type into a Python interpreter: for x in (1,2,3) and receive a result? The documentation for list(), for example suggests constructor expects an iterable but it's unclear to me what's going on.

deetsb
  • 87
  • 1
  • 8
  • 3
    https://docs.python.org/3/reference/expressions.html#generator-expressions – jonrsharpe May 27 '20 at 20:59
  • You can do `for x in (1,2,3):print(x)` yes, the iterable is a tuple here – azro May 27 '20 at 20:59
  • True. But you can do this: `(x for x in (1,2,3))` and is referred to as a generator sequence / expression. A basic example of the `dict` example in question. And just to note; you’re missing a closing `)` in your example, which is why it doesn’t make sense. – S3DEV May 27 '20 at 20:59
  • 2
    @MichaelSilverstein the example shown *isn't* a comprehension, although you could write the same functionality as a dict comprehension. – jonrsharpe May 27 '20 at 21:03
  • Can you please [edit] your question to clarify what parts about that statement you *do* understand? Do you know what an iterable is? Are you familiar with ``for`` loop *statements*? Did you consult the documentation? – MisterMiyagi May 27 '20 at 21:03
  • You have a small typo where the bracket is supposed to end :) – Red May 27 '20 at 21:04
  • Also take note: The quote cited is not strictly correct. This does *not* pass a *sequence* of tuples to ``dict``. The result of the ``... for ... in ... if ...`` is a generator of tuples, or more generally only an iterable/iterator of tuples. – MisterMiyagi May 27 '20 at 21:04
  • 1
    @MisterMiyagi it's not a sequence [in the Python sense](https://docs.python.org/3/glossary.html#term-sequence), no. – jonrsharpe May 27 '20 at 21:06
  • 1
    @S3DEV: Whoops, thanks for the typo catch. Yes, there should be an ending parenthesis. – deetsb May 27 '20 at 21:28
  • @MisterMiyagi. D'oh. I just forgot what the syntax is for a generator function, and was a bit thrown off when he called it a sequence. You figured it out, I think I took it a bit too literally. Thank you! – deetsb May 27 '20 at 21:30
  • @jonrsharpe Thanks for refreshing me with the docs/noticing that I was being a literal (pun intended) dumb-dumb! – deetsb May 27 '20 at 21:38

2 Answers2

1

dict can takes an iterable of key/value pairs to construct a new instance. The expression

(key, value) for key, value in prices.items() if value > 200

is a generator expression; the result is a value of type generator, which (when iterated over) yields those tuples from prices.items() whose second element is greater than 200.

Another way to create a generator is with a generator function:

def foo(p):
    for key, value in p.items():
        if value > 200:
            yield key, value

d = dict(foo(prices))
chepner
  • 497,756
  • 71
  • 530
  • 681
0
p1 = dict((key, value) for key, value in prices.items() if value > 200)

is the equivalent of:

p1 = {}
for key,value in prices.items():
    if value > 200:
        p1.update({key, value})

prices is a dict, so prices,items will return something like this:

dict_items([(key1, value1), (key2, value2)])

Red
  • 26,798
  • 7
  • 36
  • 58
  • 2
    Why the expensive `p1.update({key, value})` instead of the cheaper `p1[key] = value` -- I see people do this but I never understand why. – cdlane May 27 '20 at 21:31