FAQ
I have some code like this...

self.write(
'''
lots of stuff here with %(these)s named expressions
'''
% vars(self)
)

Then I wanted to add an item to the dict vars(self), so I tried :

vars(self)+{'x':'123','y':'345'}

This doesn't work, perhaps because no one could decide what should happen
to keys which already exist in the dict? (I'd say throw an exception).

Can I add two dicts in a way which is not cumbersome to the above % string
operation? Is this another case of writing my own function, or does a
builtin (or similar) already exist for this?

Search Discussions

  • Mackstann at Aug 29, 2003 at 4:22 am
    On Fri, Aug 29, 2003 at 04:11:09AM +0000, Afanasiy wrote:
    [ ... ]
    Then I wanted to add an item to the dict vars(self), so I tried :

    vars(self)+{'x':'123','y':'345'}

    This doesn't work, perhaps because no one could decide what should happen
    to keys which already exist in the dict? (I'd say throw an exception).

    Can I add two dicts in a way which is not cumbersome to the above % string
    operation? Is this another case of writing my own function, or does a
    builtin (or similar) already exist for this?
    You can use dict.update(), however, this works in place, so you'll have
    to do it outside of the actual string% statement.

    d = {"a": 1, "b": 2}
    d.update({'x':'123','y':'345'})

    print "%(..)s %(..)d ..." % d

    --
    m a c k s t a n n mack @ incise.org http://incise.org
    So, what's with this guy Gideon, anyway?
    And why can't he ever remember his Bible?
  • Erik Max Francis at Aug 29, 2003 at 5:07 am

    Afanasiy wrote:

    Can I add two dicts in a way which is not cumbersome to the above %
    string
    operation? Is this another case of writing my own function, or does a
    builtin (or similar) already exist for this?
    combinedDict = aDict.copy()
    combinedDict.update(anotherDict)

    If that's cumbersome, don't really know what you'd consider
    non-cumbersome.

    --
    Erik Max Francis && max at alcyone.com && http://www.alcyone.com/max/
    __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    / \ The revolution will not televised
    \__/ Public Enemy
  • Afanasiy at Aug 29, 2003 at 6:17 am

    On Thu, 28 Aug 2003 22:07:06 -0700, Erik Max Francis wrote:
    Afanasiy wrote:
    Can I add two dicts in a way which is not cumbersome to the above %
    string
    operation? Is this another case of writing my own function, or does a
    builtin (or similar) already exist for this?
    combinedDict = aDict.copy()
    combinedDict.update(anotherDict)

    If that's cumbersome, don't really know what you'd consider
    non-cumbersome.
    Don't really know if you're asking, but :

    vars(self)+{'x':'123','y':'345'}

    I would consider that non-cumbersome. ;-)

    My only guess why that doesn't exist is that no one decided what to do on
    like keys. Use existing, overwrite, or throw exception (my preference).
  • Erik Max Francis at Aug 29, 2003 at 6:40 am

    Afanasiy wrote:

    My only guess why that doesn't exist is that no one decided what to do
    on
    like keys. Use existing, overwrite, or throw exception (my
    preference).
    Yes, it's likely. In fact, this discussion only just came up a few days
    ago.

    --
    Erik Max Francis && max at alcyone.com && http://www.alcyone.com/max/
    __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    / \ An ounce of hypocrisy is worth a pound of ambition.
    \__/ Michael Korda
  • Alex Martelli at Aug 29, 2003 at 8:40 am

    Afanasiy wrote:
    On Thu, 28 Aug 2003 22:07:06 -0700, Erik Max Francis wrote:

    Afanasiy wrote:
    Can I add two dicts in a way which is not cumbersome to the above %
    string
    operation? Is this another case of writing my own function, or does a
    builtin (or similar) already exist for this?
    combinedDict = aDict.copy()
    combinedDict.update(anotherDict)

    If that's cumbersome, don't really know what you'd consider
    non-cumbersome.
    Don't really know if you're asking, but :

    vars(self)+{'x':'123','y':'345'}

    I would consider that non-cumbersome. ;-)
    So, what about:

    def dict_add(adict, another):
    result = adict.copy()
    result.update(another)
    return result

    and then dict_add(vars(self), {'x':'123','y':'345'}) ? But in fact
    you can do even better...:

    def dad(_adict, _another={}, **_yetmore):
    result = _adict.copy()
    result.update(_another)
    result.update(_yetmore)
    return result

    or in 2.3:

    def dad(_adict, _another={}, **_yetmore):
    result = _adict.copy()
    result.update(dict(_another, **_yetmore))
    return result


    and now, dad(vars(self), x='123', y='345') -- ain't that even
    LESS cumbersome? You can't do that with the syntax of + (no
    keyword arguments)

    Incidentally, in 2.3 you can ALSO spell your desired
    adict+anotherdict
    as
    dict(adict, **anotherdict)
    My only guess why that doesn't exist is that no one decided what to do on
    like keys. Use existing, overwrite, or throw exception (my preference).
    The semantics of all the existing ways of spelling dictionary addition
    and the like (update method, **kwds argument to dict in 2.3) have the
    second argument 'override' the first. A fast way to check that two
    dicts don't overlap (or perhaps more generally to get the list of the
    keys in which they do overlap) might be more generally useful, as well
    as allowing the diagnostics you want to be produced effectively. Still,
    as long as you're writing a function for the addition it's easy and
    fast to check for non-overlap:

    def dad(_adict, _another={}, **_yetmore):
    result = _adict.copy()
    result.update(dict(_another, **_yetmore))
    if len(result)!=len(_adict)+len(_another)+len(_yetmore):
    raise ValueError, "Overlapping keys on dict addition"
    return result


    Alex
  • Afanasiy at Aug 29, 2003 at 5:42 pm

    On Fri, 29 Aug 2003 08:40:01 GMT, Alex Martelli wrote:
    Afanasiy wrote:
    On Thu, 28 Aug 2003 22:07:06 -0700, Erik Max Francis <max at alcyone.com>
    wrote:
    Afanasiy wrote:
    Can I add two dicts in a way which is not cumbersome to the above %
    string
    operation? Is this another case of writing my own function, or does a
    builtin (or similar) already exist for this?
    combinedDict = aDict.copy()
    combinedDict.update(anotherDict)

    If that's cumbersome, don't really know what you'd consider
    non-cumbersome.
    Don't really know if you're asking, but :

    vars(self)+{'x':'123','y':'345'}

    I would consider that non-cumbersome. ;-)
    [snipped alex code]

    and now, dad(vars(self), x='123', y='345') -- ain't that even
    LESS cumbersome? You can't do that with the syntax of + (no
    keyword arguments)
    Since you asked...

    To me, this clouds the issue and developers using dad() may not actually
    be aware they are adding dictionaries. Any function you write is fine for
    your own use of course. I would just simply prefer {}+{}.

    I know I can write a function to add them and call that. Thank you.
  • Greg Brunet at Aug 30, 2003 at 6:17 am
    "Alex Martelli" <aleax at aleax.it> wrote in message
    news:BjE3b.7850$aG6.251286 at news1.tin.it...
    Afanasiy wrote:
    On Thu, 28 Aug 2003 22:07:06 -0700, Erik Max Francis
    <max at alcyone.com>
    wrote:
    Afanasiy wrote:
    Can I add two dicts in a way which is not cumbersome to the above
    %
    string
    operation? Is this another case of writing my own function, or
    does a
    builtin (or similar) already exist for this?
    combinedDict = aDict.copy()
    combinedDict.update(anotherDict)

    If that's cumbersome, don't really know what you'd consider
    non-cumbersome.
    Don't really know if you're asking, but :

    vars(self)+{'x':'123','y':'345'}

    I would consider that non-cumbersome. ;-)
    So, what about:

    def dict_add(adict, another):
    result = adict.copy()
    result.update(another)
    return result

    and then dict_add(vars(self), {'x':'123','y':'345'}) ? But in fact
    you can do even better...:
    ... lots of other good ideas...

    But what about something like this:
    class xdict(dict):
    ... def __add__(self,dict2):
    ... result = self.copy()
    ... result = result.update(dict2)
    ...

    I was hoping that would allow:
    a=xdict({'y': 456, 'x': 111})
    b=xdict({'y': 444, 'z': 789})
    a+b
    but instead of the result which I hoped for, I get the following:

    Traceback (most recent call last):
    File "<interactive input>", line 1, in ?
    TypeError: unsupported operand type(s) for +: 'xdict' and 'xdict'

    So I can't implement '+' operator for dictionaries - why not?

    --
    Greg
  • Greg Brunet at Aug 30, 2003 at 6:36 am
    "Greg Brunet" <gregbrunet at NOSPAMsempersoft.com> wrote in message
    news:vl0gbotgl3sibf at corp.supernews.com...
    But what about something like this:
    class xdict(dict):
    ... def __add__(self,dict2):
    ... result = self.copy()
    ... result = result.update(dict2)
    ...

    I was hoping that would allow:
    a=xdict({'y': 456, 'x': 111})
    b=xdict({'y': 444, 'z': 789})
    a+b
    but instead of the result which I hoped for, I get the following:

    Traceback (most recent call last):
    File "<interactive input>", line 1, in ?
    TypeError: unsupported operand type(s) for +: 'xdict' and 'xdict'

    So I can't implement '+' operator for dictionaries - why not?

    Ooops - that should have been:
    return result.update(dict2)

    in the last line, but still, shouldn't that have mapped the "+" operator
    for xdict objects?

    --
    Greg
  • Greg Brunet at Aug 30, 2003 at 7:48 am
    "Greg Brunet" <gregbrunet at NOSPAMsempersoft.com> wrote in message
    news:vl0heutm63na0 at corp.supernews.com...
    "Greg Brunet" <gregbrunet at NOSPAMsempersoft.com> wrote in message
    news:vl0gbotgl3sibf at corp.supernews.com...
    But what about something like this:
    class xdict(dict):
    ... def __add__(self,dict2):
    ... result = self.copy()
    ... result = result.update(dict2)
    ... I was getting sloppy in the interactive mode. Instead I did this &
    it seems to work properly:


    class xdict(dict):
    def add(self,dict2):
    result = self.copy()
    result.update(dict2)
    return result

    def __add__(self,dict2):
    result = self.copy()
    result.update(dict2)
    return result

    def __iadd__(self,dict2):
    self.update(dict2)
    return self

    a=xdict({'x':1})
    b=xdict({'y':2})
    print
    print "Add:", a.add(b)
    print "+:", a+b
    print "a:",a,"b:",b
    a+=b
    print "+= (a=):", a

    Results:
    Add: {'y': 2, 'x': 1}
    +: {'y': 2, 'x': 1}
    a: {'x': 1} b: {'y': 2}
    += (a=): {'y': 2, 'x': 1}


    --
    Greg
  • Alex Martelli at Aug 30, 2003 at 7:52 am

    Greg Brunet wrote:

    "Greg Brunet" <gregbrunet at NOSPAMsempersoft.com> wrote in message
    news:vl0gbotgl3sibf at corp.supernews.com...
    But what about something like this:
    class xdict(dict):
    ... def __add__(self,dict2):
    ... result = self.copy()
    ... result = result.update(dict2)
    ...
    Ooops - that should have been:
    return result.update(dict2)

    in the last line, but still, shouldn't that have mapped the "+" operator
    for xdict objects?
    You're returning None in both your actual code and the "should have been",
    but the general approach is workable -- e.g. with Python 2.3:
    class xdict(dict):
    ... def __add__(self, other):
    ... return xdict(self, **other)
    ...
    xdict({1:2, 3:4})+{5:6}
    {1: 2, 3: 4, 5: 6}
    >>>

    Alex
  • John Roth at Aug 30, 2003 at 11:36 am
    "Greg Brunet" <gregbrunet at NOSPAMsempersoft.com> wrote in message
    news:vl0gbotgl3sibf at corp.supernews.com...
    "Alex Martelli" <aleax at aleax.it> wrote in message
    news:BjE3b.7850$aG6.251286 at news1.tin.it...
    Afanasiy wrote:
    On Thu, 28 Aug 2003 22:07:06 -0700, Erik Max Francis
    <max at alcyone.com>
    wrote:
    Afanasiy wrote:
    Can I add two dicts in a way which is not cumbersome to the above
    %
    string
    operation? Is this another case of writing my own function, or
    does a
    builtin (or similar) already exist for this?
    combinedDict = aDict.copy()
    combinedDict.update(anotherDict)

    If that's cumbersome, don't really know what you'd consider
    non-cumbersome.
    Don't really know if you're asking, but :

    vars(self)+{'x':'123','y':'345'}

    I would consider that non-cumbersome. ;-)
    So, what about:

    def dict_add(adict, another):
    result = adict.copy()
    result.update(another)
    return result

    and then dict_add(vars(self), {'x':'123','y':'345'}) ? But in fact
    you can do even better...:
    ... lots of other good ideas...

    But what about something like this:
    class xdict(dict):
    ... def __add__(self,dict2):
    ... result = self.copy()
    ... result = result.update(dict2)
    ...

    I was hoping that would allow:
    a=xdict({'y': 456, 'x': 111})
    b=xdict({'y': 444, 'z': 789})
    a+b
    but instead of the result which I hoped for, I get the following:

    Traceback (most recent call last):
    File "<interactive input>", line 1, in ?
    TypeError: unsupported operand type(s) for +: 'xdict' and 'xdict'

    So I can't implement '+' operator for dictionaries - why not?
    The special functions can only be defined in the class
    definition. They cannot be added afterwards. This is a
    compiler optimization to avoid having to do dictionary
    lookups on every operator.

    If you want to do this, subclass dict.

    John Roth
    --
    Greg

  • Alex Martelli at Aug 29, 2003 at 8:48 am

    Afanasiy wrote:

    I have some code like this...

    self.write(
    '''
    lots of stuff here with %(these)s named expressions
    '''
    % vars(self)
    )

    Then I wanted to add an item to the dict vars(self), so I tried :

    vars(self)+{'x':'123','y':'345'}

    This doesn't work, perhaps because no one could decide what should happen
    to keys which already exist in the dict? (I'd say throw an exception).

    Can I add two dicts in a way which is not cumbersome to the above % string
    operation? Is this another case of writing my own function, or does a
    builtin (or similar) already exist for this?
    In Python 2.3, you can, if you wish, code:

    self.write(
    '''
    lots of stuff here with %(these)s named expressions
    '''
    % dict(vars(self), x='123', y='345')
    )

    thanks to the new feature of dict of allowing a **kwds argument (with
    the 'obvious' semantics, however: named keys override keys already
    present in the first argument -- if you need to diagnose overlap and
    raise an exception thereupon, you'll have to do that separately).

    More generally, if you had an existing dict D you wanted to "add" to
    vars(self), rather than a literal, you could code:

    self.write(
    '''
    lots of stuff here with %(these)s named expressions
    '''
    % dict(vars(self), **D)
    )


    Alex
  • Michele Simionato at Aug 29, 2003 at 12:40 pm
    Afanasiy <abelikov72 at hotmail.com> wrote in message news:<86ktkvkd05e88hu14hjudmfvbul7slfgkt at 4ax.com>...
    I have some code like this...

    self.write(
    '''
    lots of stuff here with %(these)s named expressions
    '''
    % vars(self)
    )

    Then I wanted to add an item to the dict vars(self), so I tried :

    vars(self)+{'x':'123','y':'345'}

    This doesn't work, perhaps because no one could decide what should happen
    to keys which already exist in the dict? (I'd say throw an exception).

    Can I add two dicts in a way which is not cumbersome to the above % string
    operation? Is this another case of writing my own function, or does a
    builtin (or similar) already exist for this?
    Here is a possibile solution:

    class attributes(dict):
    def __init__(self,obj):
    if isinstance(obj,dict):
    self.update(obj)
    elif hasattr(obj,'__dict__'):
    self.update(obj.__dict__)
    else:
    raise TypeError("Dictionary or object with a __dict__ required")
    def __add__(self,other):
    self.update(other)
    return self.__class__(self)
    __radd__=__add__

    class C(object):
    def __init__(self,x,y):
    self.x=x
    self.y=y


    c=C(1,2)
    print attributes(c)
    print attributes(c)+{'z':3}
    print {'z':3}+attributes(c)


    Michele Simionato, Ph. D.
    MicheleSimionato at libero.it
    http://www.phyast.pitt.edu/~micheles
    --- Currently looking for a job ---

    http://www.strakt.com/dev_talks.html

    http://www.ibm.com/developerworks/library/l-pymeta2/?ca=dnt-434
  • Christos TZOTZIOY Georgiou at Aug 29, 2003 at 1:01 pm
    On 29 Aug 2003 05:40:15 -0700, rumours say that mis6 at pitt.edu (Michele
    Simionato) might have written:

    [snip]
    def __add__(self,other):
    self.update(other)
    return self.__class__(self)
    hm... I am not sure about this; it's not iadd, so you shouldn't modify
    self.

    Perhaps you should (untested):
    def __add__(self, other):
    temp = self.copy()
    temp.update(other)
    return temp
    --
    TZOTZIOY, I speak England very best,
    Microsoft Security Alert: the Matrix began as open source.
  • Michele Simionato at Aug 29, 2003 at 7:17 pm
    Christos "TZOTZIOY" Georgiou <tzot at sil-tec.gr> wrote in message news:<mejukv8soj1phieta0k3gl2n2v9lucvjde at 4ax.com>...
    On 29 Aug 2003 05:40:15 -0700, rumours say that mis6 at pitt.edu (Michele
    Simionato) might have written:

    [snip]
    def __add__(self,other):
    self.update(other)
    return self.__class__(self)
    hm... I am not sure about this; it's not iadd, so you shouldn't modify
    self.

    Perhaps you should (untested):
    def __add__(self, other):
    temp = self.copy()
    temp.update(other)
    return temp
    As you wish ;)

    Michele Simionato, Ph. D.
    MicheleSimionato at libero.it
    http://www.phyast.pitt.edu/~micheles
    --- Currently looking for a job ---

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedAug 29, '03 at 4:11a
activeAug 30, '03 at 11:36a
posts16
users8
websitepython.org

People

Translate

site design / logo © 2022 Grokbase