Re: Why no '|' operator for dict?

2018-02-05 Thread Andre Müller
You can use keyword-argument unpacking in a dict-constructor.
Values of duplicate keys are overwritten from left to right. The last wins.

>>> dict1 = {'foo': 13, 'bar': 42}
>>> dict2 = {'foo': 42, 'hello': 'world'}

>>> {**dict1, **dict2}
{'bar': 42, 'foo': 42, 'hello': 'world'}

{**dict2, **dict1}
{'bar': 42, 'foo': 13, 'hello': 'world'}

You can make a Class for this task, if you need it very often:

class UDict(dict):
def __or__(self, other):
if not isinstance(other, (self.__class__, dict)):
raise ValueError('Is not a dict!')
return {**self, **other}
__ror__ = __or__

>>> UDict({'foo': 1, 'bar': 1337}) | UDict({'bar': 43})
{'bar': 43, 'foo': 1}
>>> UDict({'foo': 1, 'bar': 1337}) | {'bar': 43}
{'bar': 43, 'foo': 1}
>>> {'foo':42} | UDict({'foo': 1, 'bar': 1337})
{'bar': 1337, 'foo': 42}


Greetings
Andre

Steven D'Aprano  schrieb am Mo., 5.
Feb. 2018 um 11:03 Uhr:

> On Mon, 05 Feb 2018 01:14:53 -0700, Ian Kelly wrote:
>
> > On Mon, Feb 5, 2018 at 12:35 AM, Frank Millman 
> > wrote:
> >> So I have 2 questions -
> >>
> >> 1. Is there any particular reason why '|' is not supported?
> >
> > '|' is the set union operation, roughly equivalent to the set.union
> > method. Dicts don't have a union operation. If they did, and the same
> > key were found in both sets, what would be the value of that key in the
> > union?
>
> Obviously it should be a quantum superposition of the two values, which
> remains uncertain until such time as you actually print the value and
> observe it.
>
>
>
>
> --
> Steve
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Why no '|' operator for dict?

2018-02-05 Thread Steven D'Aprano
On Mon, 05 Feb 2018 01:14:53 -0700, Ian Kelly wrote:

> On Mon, Feb 5, 2018 at 12:35 AM, Frank Millman 
> wrote:
>> So I have 2 questions -
>>
>> 1. Is there any particular reason why '|' is not supported?
> 
> '|' is the set union operation, roughly equivalent to the set.union
> method. Dicts don't have a union operation. If they did, and the same
> key were found in both sets, what would be the value of that key in the
> union?

Obviously it should be a quantum superposition of the two values, which 
remains uncertain until such time as you actually print the value and 
observe it.




-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Why no '|' operator for dict?

2018-02-05 Thread Serhiy Storchaka

05.02.18 10:14, Ian Kelly пише:

On Mon, Feb 5, 2018 at 12:35 AM, Frank Millman  wrote:

So I have 2 questions -

1. Is there any particular reason why '|' is not supported?


'|' is the set union operation, roughly equivalent to the set.union
method. Dicts don't have a union operation. If they did, and the same
key were found in both sets, what would be the value of that key in
the union?


2. Is there a better way to do what I want?


The dict.items() view is explicitly set-like and can be unioned, so
you can do this:

py> dict(d1.items() | d2.items())


This doesn't work with non-hashable values.

The simplest (and perhaps the most efficient) way in recent Python 
versions is:


{**d1, **d2}

In old Python versions this should be written as

d = dict(d1)
d.update(d2)

--
https://mail.python.org/mailman/listinfo/python-list


Re: Why no '|' operator for dict?

2018-02-05 Thread Terry Reedy

On 2/5/2018 2:35 AM, Frank Millman wrote:

I recently learned that you can create a set 'on-the-fly' from two 
existing sets using the '|' operator -


Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 
bit (AMD64)] on win32

Type "help", "copyright", "credits" or "license" for more information.


set_1 = set(('a', 'b', 'c'))
set_2 = set(('d',))
set_1 | set_2

{'d', 'a', 'c', 'b'}


I was hoping that I could do the same with a dictionary, but it does not 
work -


If you know keys are unique or you want keep the second value for a 
duplicate (equal) key,


>>> d1 = {1: 'one', 2: 'two'}; d2 = {3: 'three', 1:'One'}
>>> d3 = d1.copy()
>>> d3.update(d2)
>>> d3
{1: 'One', 2: 'two', 3: 'three'}


--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: Why no '|' operator for dict?

2018-02-05 Thread Maxime S
2018-02-05 9:14 GMT+01:00 Ian Kelly :
> On Mon, Feb 5, 2018 at 12:35 AM, Frank Millman  wrote:
>> 2. Is there a better way to do what I want?
>
> The dict.items() view is explicitly set-like and can be unioned, so
> you can do this:
>
> py> dict(d1.items() | d2.items())
>
> As to the question of which value will appear in the union in the case
> of duplicate keys, it will be whichever one arbitrarily appears later
> in the iteration order of the intermediate set.

Since Python 3.5, it is also possible to use PEP448 generalized unpacking:

dict([*d1.items(), *d2.items()])

In which case the value that appears in case of duplicate keys is
better defined, it will be the one appearing in the last dictionnary.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Why no '|' operator for dict?

2018-02-05 Thread Frank Millman
"Ian Kelly"  wrote in message 
news:calwzidkp3ls4s-zi3ax6no-68kw4_xdozvwa-cj+oz+apqr...@mail.gmail.com...


On Mon, Feb 5, 2018 at 12:35 AM, Frank Millman  wrote:
> So I have 2 questions -
>
> 1. Is there any particular reason why '|' is not supported?

'|' is the set union operation, roughly equivalent to the set.union
method. Dicts don't have a union operation. If they did, and the same
key were found in both sets, what would be the value of that key in
the union?

> 2. Is there a better way to do what I want?

The dict.items() view is explicitly set-like and can be unioned, so
you can do this:

py> dict(d1.items() | d2.items())



Excellent explanation, and excellent solution!

Thanks very much.

Frank


--
https://mail.python.org/mailman/listinfo/python-list


Re: Why no '|' operator for dict?

2018-02-05 Thread Ian Kelly
On Mon, Feb 5, 2018 at 12:35 AM, Frank Millman  wrote:
> So I have 2 questions -
>
> 1. Is there any particular reason why '|' is not supported?

'|' is the set union operation, roughly equivalent to the set.union
method. Dicts don't have a union operation. If they did, and the same
key were found in both sets, what would be the value of that key in
the union?

> 2. Is there a better way to do what I want?

The dict.items() view is explicitly set-like and can be unioned, so
you can do this:

py> dict(d1.items() | d2.items())

As to the question of which value will appear in the union in the case
of duplicate keys, it will be whichever one arbitrarily appears later
in the iteration order of the intermediate set.
-- 
https://mail.python.org/mailman/listinfo/python-list


Why no '|' operator for dict?

2018-02-04 Thread Frank Millman

Hi all

I recently learned that you can create a set 'on-the-fly' from two existing 
sets using the '|' operator -


Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit 
(AMD64)] on win32

Type "help", "copyright", "credits" or "license" for more information.


set_1 = set(('a', 'b', 'c'))
set_2 = set(('d',))
set_1 | set_2

{'d', 'a', 'c', 'b'}




I was hoping that I could do the same with a dictionary, but it does not 
work -



dict_1 = {1: 'one', 2: 'two'}
dict_2 = {3: 'three'}
dict_1 | dict_2

Traceback (most recent call last):
 File "", line 1, in 
TypeError: unsupported operand type(s) for |: 'dict' and 'dict'




The best that I can come up with is -

dict([(k, v) for k, v in dict_1.items()] + [(k, v) for k, v in 
dict_2.items()])

{1: 'one', 2: 'two', 3: 'three'}




So I have 2 questions -

1. Is there any particular reason why '|' is not supported?

2. Is there a better way to do what I want?

Thanks

Frank Millman


--
https://mail.python.org/mailman/listinfo/python-list