Mailing List Archive

Why operations between dict views return a set and not a frozenset?
$ python
Python 3.10.0 (heads/3.10-dirty:f6e8b80d20, Nov 18 2021, 19:16:18)
[GCC 10.1.1 20200718] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = {1:2}
>>> c = {1:2, 3:4}
>>> c.keys() - a.keys()
{3}
>>>


Why not frozenset({3})?
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
On Wed, Jan 5, 2022 at 5:29 AM Marco Sulla <Marco.Sulla.Python@gmail.com> wrote:
>
> $ python
> Python 3.10.0 (heads/3.10-dirty:f6e8b80d20, Nov 18 2021, 19:16:18)
> [GCC 10.1.1 20200718] on linux
> Type "help", "copyright", "credits" or "license" for more information.
> >>> a = {1:2}
> >>> c = {1:2, 3:4}
> >>> c.keys() - a.keys()
> {3}
> >>>
>

Let's start with this.

>>> a = {1}
>>> c = {1, 3}
>>> c - a
{3}

Do you agree that this should be a set?

If so, then the next question is: should the keys view be considered
frozen or not? Remember the set of keys can change (when the
underlying dict changes).

It's not difficult to construct a frozenset from a set.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
On Tue, 4 Jan 2022 at 19:38, Chris Angelico <rosuav@gmail.com> wrote:
> [...] should the keys view be considered
> frozen or not? Remember the set of keys can change (when the
> underlying dict changes).

Well, also the items can change, but they are returned as tuples with
2 elements.

It seems to me that the stdlib, when something should return a
sequence, prefers to return a tuple. So I expected the same preference
for frozenset over set.

> It's not difficult to construct a frozenset from a set.

This sentence has the commutative property :)
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
On 04Jan2022 21:03, Marco Sulla <Marco.Sulla.Python@gmail.com> wrote:
>On Tue, 4 Jan 2022 at 19:38, Chris Angelico <rosuav@gmail.com> wrote:
>> [...] should the keys view be considered
>> frozen or not? Remember the set of keys can change (when the
>> underlying dict changes).
>
>Well, also the items can change, but they are returned as tuples with
>2 elements.
>
>It seems to me that the stdlib, when something should return a
>sequence, prefers to return a tuple. So I expected the same preference
>for frozenset over set.
>
>> It's not difficult to construct a frozenset from a set.
>
>This sentence has the commutative property :)

Indeed.

But speaking for myself, I may well want to perform additional work on
the object returned. Making a copy of it for tht purpose seems very
wasteful (imagine the set is quite large). A modifiable version can be
used immediately with no time or space cost. And it can be left alone if
it is to be unchanged. If I got a frozenset back I would inherently
have to copy it to do "modifying work".

So I prefer getting a modifiable object back.

Cheers,
Cameron Simpson <cs@cskk.id.au>
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
On Wed, Jan 5, 2022 at 7:04 AM Marco Sulla <Marco.Sulla.Python@gmail.com> wrote:
>
> On Tue, 4 Jan 2022 at 19:38, Chris Angelico <rosuav@gmail.com> wrote:
> > [...] should the keys view be considered
> > frozen or not? Remember the set of keys can change (when the
> > underlying dict changes).
>
> Well, also the items can change, but they are returned as tuples with
> 2 elements.

That's because a tuple is the correct data type when returning two
distinct items. It's not a list that has two elements in it; it's a
tuple of (key, value). Immutability is irrelevant.

> It seems to me that the stdlib, when something should return a
> sequence, prefers to return a tuple. So I expected the same preference
> for frozenset over set.

Got any examples of variable-length sequences? Usually a tuple is a
structure, not just a sequence. If something is just returning a
sequence, it'll most often return a dedicated sequence type (like
range in Py3) or a list (like lots of things in Py2).

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
On 2022-01-05 at 08:30:30 +1100,
Cameron Simpson <cs@cskk.id.au> wrote:

> On 04Jan2022 21:03, Marco Sulla <Marco.Sulla.Python@gmail.com> wrote:
> >On Tue, 4 Jan 2022 at 19:38, Chris Angelico <rosuav@gmail.com> wrote:
> >> [...] should the keys view be considered
> >> frozen or not? Remember the set of keys can change (when the
> >> underlying dict changes).
> >
> >Well, also the items can change, but they are returned as tuples with
> >2 elements.
> >
> >It seems to me that the stdlib, when something should return a
> >sequence, prefers to return a tuple. So I expected the same preference
> >for frozenset over set.
> >
> >> It's not difficult to construct a frozenset from a set.
> >
> >This sentence has the commutative property :)
>
> Indeed.
>
> But speaking for myself, I may well want to perform additional work on
> the object returned. Making a copy of it for tht purpose seems very
> wasteful (imagine the set is quite large). A modifiable version can be
> used immediately with no time or space cost. And it can be left alone if
> it is to be unchanged. If I got a frozenset back I would inherently
> have to copy it to do "modifying work".

Unless the additional work is to use it as a dictionary key, or to add
it to an existing [necessarily mutable!] set. Then again, that's not
work *on* the object returned, that's additional work *with* the object
returned.

We could go around and around on this all day. :-)

Python began with the premise of mutability. IIRC, many attempts at
immutable class instances (for use in sets or as dictionary keys) have
run into the same issues Marco Sulla is having.
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
On Wed, 5 Jan 2022 at 00:54, Chris Angelico <rosuav@gmail.com> wrote:
> That's because a tuple is the correct data type when returning two
> distinct items. It's not a list that has two elements in it; it's a
> tuple of (key, value). Immutability is irrelevant.

Immutability is irrelevant, speed no. A tuple is faster than a list
and more compact. Also frozenset is faster than set. Indeed CPython
optimises internally a

for x in {1, 2, 3}

transforming the set in a frozenset for a matter of speed. That's why
tuple is usually preferred. I expected the same for frozenset

> Got any examples of variable-length sequences?

function positional args are tuples, for example.

> Usually a tuple is a
> structure, not just a sequence.

....eh? Are you talking about the underlying C code?

> If something is just returning a
> sequence, it'll most often return a dedicated sequence type (like
> range in Py3) or a list (like lots of things in Py2).

Python 2 is now obsolete, I don't think is relevant for the discussion.

About your sentence, yes, usually a dedicated view, sequence or
generator is returned, but tuples too are really much used. A list is
returned very sporadically, for what I remember.
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
On Thu, Jan 6, 2022 at 12:05 AM Marco Sulla
<Marco.Sulla.Python@gmail.com> wrote:
>
> On Wed, 5 Jan 2022 at 00:54, Chris Angelico <rosuav@gmail.com> wrote:
> > That's because a tuple is the correct data type when returning two
> > distinct items. It's not a list that has two elements in it; it's a
> > tuple of (key, value). Immutability is irrelevant.
>
> Immutability is irrelevant, speed no. A tuple is faster than a list
> and more compact. Also frozenset is faster than set. Indeed CPython
> optimises internally a
>
> for x in {1, 2, 3}
>
> transforming the set in a frozenset for a matter of speed. That's why
> tuple is usually preferred. I expected the same for frozenset

That's an entirely invisible optimization, but it's more than just
"frozenset is faster than set". It's that a frozenset or tuple can be
stored as a function's constants, which is a massive difference.

In fact, the two data types are virtually identical in performance once created:

rosuav@sikorsky:~$ python3 -m timeit -s "stuff = {1,2,3}" "for x in stuff: pass"
5000000 loops, best of 5: 46.2 nsec per loop
rosuav@sikorsky:~$ python3 -m timeit -s "stuff = frozenset({1,2,3})"
"for x in stuff: pass"
5000000 loops, best of 5: 46.7 nsec per loop
rosuav@sikorsky:~$ python3 -m timeit -s "stuff = set(range(10000))"
"for x in stuff: pass"
5000 loops, best of 5: 82.1 usec per loop
rosuav@sikorsky:~$ python3 -m timeit -s "stuff =
frozenset(range(10000))" "for x in stuff: pass"
5000 loops, best of 5: 81.3 usec per loop

Mutability is irrelevant, and so is the speed of the data type. Having
set operations on keys views return frozensets wouldn't improve
anything.

> > Got any examples of variable-length sequences?
>
> function positional args are tuples, for example.
>
> > Usually a tuple is a
> > structure, not just a sequence.
>
> ....eh? Are you talking about the underlying C code?

No, I'm talking about purpose. In general, a list contains a sequence
of things whose order matters but which can be removed from - you can
remove one item from your shopping list and the rest still mean what
they were. A tuple has a specific set of things in a specific order,
like Cartesian coordinates. You can't just remove the x coordinate
from an (x,y,z) tuple without fundamentally changing what it is.

Function positional arguments aren't interchangeable, so it makes
sense to have them as a tuple. Removing the first argument would
redefine what all the others mean, so a tuple is correct - it's not
just a list that's been made immutable for performance's sake.
(Function *keyword* arguments, on the other hand, are different; as
long as the mapping from keys to values is maintained, you can remove
some of them and pass the rest on, without fundamentally changing
their meaning.)

Do you have any examples of actually variable-length sequences that
are tuples for speed?

Measure before claiming a speed difference.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
Op 4/01/2022 om 19:27 schreef Marco Sulla:
> $ python
> Python 3.10.0 (heads/3.10-dirty:f6e8b80d20, Nov 18 2021, 19:16:18)
> [GCC 10.1.1 20200718] on linux
> Type "help", "copyright", "credits" or "license" for more information.
>>>> a = {1:2}
>>>> c = {1:2, 3:4}
>>>> c.keys() - a.keys()
> {3}
>
> Why not frozenset({3})?

My 2 cents worths: Because dictviews mutate with the directory. That makes
them more like set than like frozenset. So operations on them produce a set.

--
Antoon Pardon.
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
On Wed, 5 Jan 2022 at 14:16, Chris Angelico <rosuav@gmail.com> wrote:
> That's an entirely invisible optimization, but it's more than just
> "frozenset is faster than set". It's that a frozenset or tuple can be
> stored as a function's constants, which is a massive difference.

Can you explain this?

> In fact, the two data types are virtually identical in performance once created [...]

This is really strange, since in theory frozenset should not have to
check if itself is mutated during the iteration, on each cycle. So the
speed should be noticeable faster. Maybe frozenset was not optimised,
because the use case is really little and will add potentially useless
C code? Furthermore, more the code, more the memory consumption and
less the speed. I have to check setobject.c.

> Function positional arguments aren't interchangeable, so it makes
> sense to have them as a tuple.

You are wrong, since kwarg is a dict. Indeed I proposed to use
frozendict for kwargs, and Guido said that it's a pity that this will
break a lot of existing Python code :D, since the fact that args is
_immutable_ and kwargs not always bothered him.

Anyway, I'm starting to think that neither set nor frozenset are good
for dict items:

(venv_3_10) marco@buzz:~$ python
Python 3.10.0 (heads/3.10-dirty:f6e8b80d20, Nov 18 2021, 19:16:18)
[GCC 10.1.1 20200718] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = {1: 2}
>>> b = {3: []}
>>> a | b
{1: 2, 3: []}
>>> a.items() | b.items()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>>
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
On Thu, Jan 6, 2022 at 8:01 AM Marco Sulla <Marco.Sulla.Python@gmail.com> wrote:
>
> On Wed, 5 Jan 2022 at 14:16, Chris Angelico <rosuav@gmail.com> wrote:
> > That's an entirely invisible optimization, but it's more than just
> > "frozenset is faster than set". It's that a frozenset or tuple can be
> > stored as a function's constants, which is a massive difference.
>
> Can you explain this?

Play around with dis.dis and timeit.

> > Function positional arguments aren't interchangeable, so it makes
> > sense to have them as a tuple.
>
> You are wrong, since kwarg is a dict. Indeed I proposed to use
> frozendict for kwargs, and Guido said that it's a pity that this will
> break a lot of existing Python code :D, since the fact that args is
> _immutable_ and kwargs not always bothered him.

Excuse me? I mentioned kwargs in the part that you removed from the
quote, and the part you're quoting explicitly says "positional
arguments".

> Anyway, I'm starting to think that neither set nor frozenset are good
> for dict items:
>
> (venv_3_10) marco@buzz:~$ python
> Python 3.10.0 (heads/3.10-dirty:f6e8b80d20, Nov 18 2021, 19:16:18)
> [GCC 10.1.1 20200718] on linux
> Type "help", "copyright", "credits" or "license" for more information.
> >>> a = {1: 2}
> >>> b = {3: []}
> >>> a | b
> {1: 2, 3: []}
> >>> a.items() | b.items()
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> TypeError: unhashable type: 'list'
> >>>

Well yes. Only dict keys can be considered to be set-like. I don't
know WHAT you think you're trying to do here, but if you ever thought
of set operations on dict values, you may want to completely rethink
what you're doing.

Performance is not an automatic result of immutability. That simply
isn't how it works.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
On Wed, 5 Jan 2022 at 23:02, Chris Angelico <rosuav@gmail.com> wrote:
>
> On Thu, Jan 6, 2022 at 8:01 AM Marco Sulla <Marco.Sulla.Python@gmail.com> wrote:
> >
> > On Wed, 5 Jan 2022 at 14:16, Chris Angelico <rosuav@gmail.com> wrote:
> > > That's an entirely invisible optimization, but it's more than just
> > > "frozenset is faster than set". It's that a frozenset or tuple can be
> > > stored as a function's constants, which is a massive difference.
> >
> > Can you explain this?
>
> Play around with dis.dis and timeit.

? I don't understand. You're talking about function constants. What
are they? I can't dig deep into something if I can't know what it is.
Maybe are you talking about function default values for parameters?

> > > Function positional arguments aren't interchangeable, so it makes
> > > sense to have them as a tuple.
> >
> > You are wrong, since kwarg is a dict. Indeed I proposed to use
> > frozendict for kwargs, and Guido said that it's a pity that this will
> > break a lot of existing Python code :D, since the fact that args is
> > _immutable_ and kwargs not always bothered him.
>
> Excuse me? I mentioned kwargs in the part that you removed from the
> quote, and the part you're quoting explicitly says "positional
> arguments".

Ok, I quote also the other part:

> (Function *keyword* arguments, on the other hand, are different; as
> long as the mapping from keys to values is maintained, you can remove
> some of them and pass the rest on, without fundamentally changing
> their meaning.)

First of all, I repeat, Guido said (more or less) that in a perfect
world, kwargs are immutable. Or maybe I did not understand what he
said, maybe he said that in a perfect world also args are mutable. But
I suppose it's more probable the first hypothesis :D

Secondly, you can also get the args from a function, transform it in a
list, change something and pass it unpacked to another function. You
will not change the meaning of the tuple, since, well, you copied it
in another mutable object. The original object is untouched.

I perfectly agree that, in the majority of cases, returning an
immutable vs a mutable are a matter of... sense? Meaning? Ok, I
perfectly agree. But IMHO there are many cases in which immutable
objects are used for a matter of speed, and I bet that args is one of
them.

> > Anyway, I'm starting to think that neither set nor frozenset are good
> > for dict items:
> >
> > (venv_3_10) marco@buzz:~$ python
> > Python 3.10.0 (heads/3.10-dirty:f6e8b80d20, Nov 18 2021, 19:16:18)
> > [GCC 10.1.1 20200718] on linux
> > Type "help", "copyright", "credits" or "license" for more information.
> > >>> a = {1: 2}
> > >>> b = {3: []}
> > >>> a | b
> > {1: 2, 3: []}
> > >>> a.items() | b.items()
> > Traceback (most recent call last):
> > File "<stdin>", line 1, in <module>
> > TypeError: unhashable type: 'list'
> > >>>
>
> Well yes. Only dict keys can be considered to be set-like.

This is not true. It's at least from Python 3.6, and I think also
before, that almost the full Set API was added to both keys and items
view.
Items indeed are a sort of set, in a mathematical sense, since any
pair (key, value) is unique, even if value is mutable.

> I don't
> know WHAT you think you're trying to do here, but if you ever thought
> of set operations on dict values, you may want to completely rethink
> what you're doing.

set ops on values? Never said that :) I said that currently you can
operate on item views with set operators. This is a fact.

I also said that, since py sets accept only hashable objects, maybe
another ad-hoc object should be used for the result of the items
operations.
But maybe the change isn't worth the additional trouble. Indeed I
didn't know about the new set methods and operations on dict views
until I explored dictobject.c

> Performance is not an automatic result of immutability. That simply
> isn't how it works.

Of course. You can use a proxy and slow down almost everything much
more. Or you can simply create a version of the mutable object with
fewer methods, as more or less frozenset is. I checked the
implementation, no fast iteration is implemented. I do not understand
why in `for x in {1, 2, 3}` the set is substituted by a frozenset.
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
On Tue, Jan 11, 2022 at 10:26 AM Marco Sulla
<Marco.Sulla.Python@gmail.com> wrote:
>
> On Wed, 5 Jan 2022 at 23:02, Chris Angelico <rosuav@gmail.com> wrote:
> >
> > On Thu, Jan 6, 2022 at 8:01 AM Marco Sulla <Marco.Sulla.Python@gmail.com> wrote:
> > >
> > > On Wed, 5 Jan 2022 at 14:16, Chris Angelico <rosuav@gmail.com> wrote:
> > > > That's an entirely invisible optimization, but it's more than just
> > > > "frozenset is faster than set". It's that a frozenset or tuple can be
> > > > stored as a function's constants, which is a massive difference.
> > >
> > > Can you explain this?
> >
> > Play around with dis.dis and timeit.
>
> ? I don't understand. You're talking about function constants. What
> are they? I can't dig deep into something if I can't know what it is.
> Maybe are you talking about function default values for parameters?

No, I'm talking about constants. Every function has them.

> Of course. You can use a proxy and slow down almost everything much
> more. Or you can simply create a version of the mutable object with
> fewer methods, as more or less frozenset is. I checked the
> implementation, no fast iteration is implemented. I do not understand
> why in `for x in {1, 2, 3}` the set is substituted by a frozenset.

Constants. Like I said, play around with dis.dis, and explore what's
already happening. A set can't be a constant, a frozenset can be.
Constants are way faster than building from scratch.

Explore. Play around. I'm not going to try to explain everything in detail.

If you're delving into the details of the C implementation of the
dictionary, I would have expected you'd already be familiar with the
way that functions behave.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
Ok... so I suppose, since you're inviting me to use dis and look at the
bytecode, that are you talking about constants in assembly, so const in C?
Sorry for the confusion, I'm not so skilled in C and I know nearly nothing
about assembly. Furthermore I never look at the bytecode of any language
before, so I simply didn't understand you.

I think this is what you mean:

>>> dis.dis("for _ in {1, 2}: pass")
1 0 SETUP_LOOP 12 (to 14)
2 LOAD_CONST 3 (frozenset({1, 2}))
4 GET_ITER
>> 6 FOR_ITER 4 (to 12)
8 STORE_NAME 0 (_)
10 JUMP_ABSOLUTE 6
>> 12 POP_BLOCK
>> 14 LOAD_CONST 2 (None)
16 RETURN_VALUE
>>> a = {1, 2}
>>> dis.dis("for _ in a: pass")
1 0 SETUP_LOOP 12 (to 14)
2 LOAD_NAME 0 (a)
4 GET_ITER
>> 6 FOR_ITER 4 (to 12)
8 STORE_NAME 1 (_)
10 JUMP_ABSOLUTE 6
>> 12 POP_BLOCK
>> 14 LOAD_CONST 0 (None)
16 RETURN_VALUE


On Tue, 11 Jan 2022 at 01:05, Chris Angelico <rosuav@gmail.com> wrote:

> On Tue, Jan 11, 2022 at 10:26 AM Marco Sulla
> <Marco.Sulla.Python@gmail.com> wrote:
> >
> > On Wed, 5 Jan 2022 at 23:02, Chris Angelico <rosuav@gmail.com> wrote:
> > >
> > > On Thu, Jan 6, 2022 at 8:01 AM Marco Sulla <
> Marco.Sulla.Python@gmail.com> wrote:
> > > >
> > > > On Wed, 5 Jan 2022 at 14:16, Chris Angelico <rosuav@gmail.com>
> wrote:
> > > > > That's an entirely invisible optimization, but it's more than just
> > > > > "frozenset is faster than set". It's that a frozenset or tuple can
> be
> > > > > stored as a function's constants, which is a massive difference.
> > > >
> > > > Can you explain this?
> > >
> > > Play around with dis.dis and timeit.
> >
> > ? I don't understand. You're talking about function constants. What
> > are they? I can't dig deep into something if I can't know what it is.
> > Maybe are you talking about function default values for parameters?
>
> No, I'm talking about constants. Every function has them.
>
> > Of course. You can use a proxy and slow down almost everything much
> > more. Or you can simply create a version of the mutable object with
> > fewer methods, as more or less frozenset is. I checked the
> > implementation, no fast iteration is implemented. I do not understand
> > why in `for x in {1, 2, 3}` the set is substituted by a frozenset.
>
> Constants. Like I said, play around with dis.dis, and explore what's
> already happening. A set can't be a constant, a frozenset can be.
> Constants are way faster than building from scratch.
>
> Explore. Play around. I'm not going to try to explain everything in detail.
>
> If you're delving into the details of the C implementation of the
> dictionary, I would have expected you'd already be familiar with the
> way that functions behave.
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
On Wed, Jan 12, 2022 at 5:49 AM Marco Sulla
<Marco.Sulla.Python@gmail.com> wrote:
>
> Ok... so I suppose, since you're inviting me to use dis and look at the bytecode, that are you talking about constants in assembly, so const in C? Sorry for the confusion, I'm not so skilled in C and I know nearly nothing about assembly. Furthermore I never look at the bytecode of any language before, so I simply didn't understand you.
>

No, I'm talking about constants in Python.

> I think this is what you mean:
>
> >>> dis.dis("for _ in {1, 2}: pass")
> 1 0 SETUP_LOOP 12 (to 14)
> 2 LOAD_CONST 3 (frozenset({1, 2}))

This is a constant.

> 4 GET_ITER
> >> 6 FOR_ITER 4 (to 12)
> 8 STORE_NAME 0 (_)
> 10 JUMP_ABSOLUTE 6
> >> 12 POP_BLOCK
> >> 14 LOAD_CONST 2 (None)

This is a constant.

> 16 RETURN_VALUE
> >>> a = {1, 2}
> >>> dis.dis("for _ in a: pass")
> 1 0 SETUP_LOOP 12 (to 14)
> 2 LOAD_NAME 0 (a)
> 4 GET_ITER
> >> 6 FOR_ITER 4 (to 12)
> 8 STORE_NAME 1 (_)
> 10 JUMP_ABSOLUTE 6
> >> 12 POP_BLOCK
> >> 14 LOAD_CONST 0 (None)

This is a constant.

> 16 RETURN_VALUE
>

Try the same thing with other code and see whether you can see a
difference. In other words, *play around with dis.dis*.

If you're trying to hack on the internals of the CPython dictionary
implementation and do not understand how Python bytecode is executed,
you are doomed to make many MANY errors of judgment about performance.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
On 2022-01-11 19:49:20 +0100, Marco Sulla wrote:
> I think this is what you mean:
>
> >>> dis.dis("for _ in {1, 2}: pass")
> 1 0 SETUP_LOOP 12 (to 14)
> 2 LOAD_CONST 3 (frozenset({1, 2}))
> 4 GET_ITER
> >> 6 FOR_ITER 4 (to 12)
> 8 STORE_NAME 0 (_)
> 10 JUMP_ABSOLUTE 6
> >> 12 POP_BLOCK
> >> 14 LOAD_CONST 2 (None)
> 16 RETURN_VALUE
> >>> a = {1, 2}
> >>> dis.dis("for _ in a: pass")
> 1 0 SETUP_LOOP 12 (to 14)
> 2 LOAD_NAME 0 (a)
> 4 GET_ITER
> >> 6 FOR_ITER 4 (to 12)
> 8 STORE_NAME 1 (_)
> 10 JUMP_ABSOLUTE 6
> >> 12 POP_BLOCK
> >> 14 LOAD_CONST 0 (None)
> 16 RETURN_VALUE

I think you have omitted the part that Chris was hinting at.

>>> dis.dis("a = {1, 2};\nfor _ in a: pass")
1 0 LOAD_CONST 0 (1)
2 LOAD_CONST 1 (2)
4 BUILD_SET 2
6 STORE_NAME 0 (a)

2 8 LOAD_NAME 0 (a)
10 GET_ITER
>> 12 FOR_ITER 4 (to 18)
14 STORE_NAME 1 (_)
16 JUMP_ABSOLUTE 12
>> 18 LOAD_CONST 2 (None)
20 RETURN_VALUE

Now compare

2 LOAD_CONST 3 (frozenset({1, 2}))

with

1 0 LOAD_CONST 0 (1)
2 LOAD_CONST 1 (2)
4 BUILD_SET 2

and you see the difference between using a frozenset as a constant and
building a set at runtime.

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
Re: Why operations between dict views return a set and not a frozenset? [ In reply to ]
Thank you a lot for letting me understand :)

On Tue, 11 Jan 2022 at 22:09, Peter J. Holzer <hjp-python@hjp.at> wrote:

> On 2022-01-11 19:49:20 +0100, Marco Sulla wrote:
> > I think this is what you mean:
> >
> > >>> dis.dis("for _ in {1, 2}: pass")
> > 1 0 SETUP_LOOP 12 (to 14)
> > 2 LOAD_CONST 3 (frozenset({1, 2}))
> > 4 GET_ITER
> > >> 6 FOR_ITER 4 (to 12)
> > 8 STORE_NAME 0 (_)
> > 10 JUMP_ABSOLUTE 6
> > >> 12 POP_BLOCK
> > >> 14 LOAD_CONST 2 (None)
> > 16 RETURN_VALUE
> > >>> a = {1, 2}
> > >>> dis.dis("for _ in a: pass")
> > 1 0 SETUP_LOOP 12 (to 14)
> > 2 LOAD_NAME 0 (a)
> > 4 GET_ITER
> > >> 6 FOR_ITER 4 (to 12)
> > 8 STORE_NAME 1 (_)
> > 10 JUMP_ABSOLUTE 6
> > >> 12 POP_BLOCK
> > >> 14 LOAD_CONST 0 (None)
> > 16 RETURN_VALUE
>
> I think you have omitted the part that Chris was hinting at.
>
> >>> dis.dis("a = {1, 2};\nfor _ in a: pass")
> 1 0 LOAD_CONST 0 (1)
> 2 LOAD_CONST 1 (2)
> 4 BUILD_SET 2
> 6 STORE_NAME 0 (a)
>
> 2 8 LOAD_NAME 0 (a)
> 10 GET_ITER
> >> 12 FOR_ITER 4 (to 18)
> 14 STORE_NAME 1 (_)
> 16 JUMP_ABSOLUTE 12
> >> 18 LOAD_CONST 2 (None)
> 20 RETURN_VALUE
>
> Now compare
>
> 2 LOAD_CONST 3 (frozenset({1, 2}))
>
> with
>
> 1 0 LOAD_CONST 0 (1)
> 2 LOAD_CONST 1 (2)
> 4 BUILD_SET 2
>
> and you see the difference between using a frozenset as a constant and
> building a set at runtime.
>
> hp
>
> --
> _ | Peter J. Holzer | Story must make more sense than reality.
> |_|_) | |
> | | | hjp@hjp.at | -- Charles Stross, "Creative writing
> __/ | http://www.hjp.at/ | challenge!"
> --
> https://mail.python.org/mailman/listinfo/python-list
>
--
https://mail.python.org/mailman/listinfo/python-list