Comments (22)
That sure is interesting functionality, but I'm not sure it belongs on the Dict class. If it's to be included I think I'd prefer something like:
>>> from addict import Dict, extend
>>> a = Dict({...})
>>> b = Dict({...})
>>> c = extend(a, b)
where extend works on all dicts, and resides outside the Dict class.
However, perhaps there are more fitting Python modules to include this in? If not, then we perhaps should include it here 👍
from addict.
Honestly I've searched all around the web for something like that, and I only found that snippet. Rather than including 10 modules just to get one thing from one, and one from the other, I would liketo have a full-blown library that just does all the stuff :)
I would love also something like:
>>> from adddict import Dict
>>> a = Dict({...})
>>> b = Dict({...})
>>> c = a.extend(b, ...)
Cleaner and also easier to understand :) Just my two cents, but thanks for getting this in consideration!
from addict.
I see your point. I'll keep this issue open, and get back to it when I've thought about it for a while 👍
from addict.
Perfect, I'll watch this so I can be notified when it's done :) thanks!
from addict.
NP, thanks for contributing @julianxhokaxhiu!
from addict.
Suggestion:
Consider using using the plus operator ('+') for merging addict with a dictionary / with other addicts.
'+' is not implemented for standard dictionaries:
{}+{}
(TypeError: unsupported operand type(s) for +: 'dict' and 'dict')
but you can implement "+", in a similar way:
class Dict:
...
def __add__(self, d):
self.update(extend(self, d)) # totally NOT a working example
In that case, you could write:
new_addict = addict_obj + normal_dict
Which makes perfect sense (to me, and to some others).
from addict.
Wow, amazing suggestion! +1
from addict.
What would be the expected behavior for this test case?
prop = Dict({'a': 1, 'b': 'string', 'c': [1,2,3], 'd': {'a': 1}})
result = prop + {'a': 2, 'c': [1], 'b': 'another string', 'd': {'b': 2}}
from addict.
Would you replace or reject the value of a
from the rhs?
Do you append the string, or replace it?
Does c
get replaced or extended? A string is just an array of chars :)
I think d
is the most straightforward with d == {'a': 1, 'b': 2}
from addict.
Here is a hacked up version:
@classmethod
def _merge(self, lhs, rhs):
for key, value in lhs.iteritems():
if not key in rhs:
rhs[key] = value
elif isinstance(value, dict):
self._merge(value, rhs[key])
return rhs
def __add__(self, rhs):
return self._merge(self.to_dict(), rhs)
And a test:
def test_plus_operator_with_dict(self):
prop = Dict({'a': 1, 'b': 'string', 'c': [1,2,3], 'd': {'a': 1}})
result = prop + {'a': 2, 'c': [1], 'b': 'another string', 'd': {'b': 2}}
self.assertDictEqual(result, {'a': 2, 'b': 'another string', 'c': [1,2,3,1], 'd': {'a': 1, 'b': 2}})
Let me know how you guys want to go forward, I can clean up and send a PR
from addict.
OOPS, i didn't think of merging different data-types :(
it turns merging into a very UNDEFINED method, that can be implemented in different ways, each with its own reasons.
I just tested your (sabhiram's) code in jQuery's Extend (with "true" as first argument).
it MERGED the list items; i.e. [1,2,3] + [1] ==> [1,2,3] and also [1] + [1,2,3] ==> [1,2,3] .
You suggested to EXTEND the lists, i.e. [1]+[1,2,3] ==> [1,2,3,1](although i don't see where it's done in your code snippet).
singletons were repalced with the newer dictionary, as in update().
i'd expect sets to be merged, too.
But it's not that obvious, isn't it?
from addict.
Yea we could end up special casing all those types I suppose, but it would stop being pythonic I feel. I suppose we could allow some flexibility in what is merged and what is replaced, but again adds complexity in the caller.
from addict.
+1 to extend
from addict.
Hey guys,
Great discussion going on here. As I've previously stated, I'm not entirely certain where I stand on this. To me, the standard dict update is quite clear, whereas I feel that the the extend is a bit hard to grasp, see @sabhiram's and @shula's comments. With that said, I guess the extend could be a nice complementary function to the update, if the functionality and use case is clearly documented. I welcome pull requests and further discussion around the subject.
Again, thanks for contributing!
from addict.
I stumbled across this thread (and addict) while trying to find a solution to my own version of $.extend().
I see that you added it to addict, but what was the outcome of merging two different types? For my version I just overwrite the first type with the second. So if new.a = ['a','list']
and newer.a = 'a string'
then newest = extend(new, newer)
, newest.a = 'a string'
.
from addict.
Hey @the4tress, we have not yet added it to addict. But we just got a new update
function from #44, and I think addict is ready for this as well. I encourage everyone (@julianxhokaxhiu, @shula and @sabhiram, @the4tress +++) to work on it if they have the time. I will probably have a look myself.
I am not sure how to answer this question as it is not yet implemented, so we could def. need help in planning the method and it's output. Thanks!
from addict.
I forked and added a slightly modified version of my extend(). I'm not sure how to update the object though. Right now I'm using a = a.extend()
when I should just use a.extend()
.
My version also has some list options. There are several examples in the way-too-long block comment.
Let me know what you think. This is my first time contributing to somebody else's project so go easy on me. I'll clean up and PEP8 the code later.
Here is my version: https://github.com/the4tress/addict/blob/master/addict/addict.py
from addict.
So, at first glance, I must say that it looks like a very thorough job. Well done, @the4tress 👍
I'd like to take some time to go through the code, and in the meantime encourage you to write some test cases for this. As I take a look, I'd also like to engage @burk, @sabhiram, @shula and @julianxhokaxhiu get their opinions on this implementation.
from addict.
Sorry @mewwts this period I'm really having no time to spend on this, but I'll look at this asap. But it's a good thing that now we have something concrete to analyze :)
What I can say for now is that my expectations are that is working like jQuery extend is working. But if it has plus features like a smarter way to merge, than it's more than welcome.
I'll give you a more dev friendly feedback asap :) Thanks in advice for everything guys!
from addict.
Sorry, between a new job, school and twin two-year-olds I can't commit any time to this for a few weeks. I know this probably needs a lot of work and maybe has some features you don't really need/want, but I was just hoping to get a sample out there for you guys to improve on.
I take my CCNA Sec in a couple weeks. After that I should have more time to write tests and clean up the code.
What am I doing wrong where I can't use a.extend()
?
Also, I just realized my examples in the comment block don't really match up. I was testing as I was writing at the same time but it should give an idea how its supposed to work.
from addict.
@the4tress @julianxhokaxhiu no worries, I'll try to squeeze in a couple of hours on this in the coming week. The only issue is that I'm not the one requesting this feature so the usecases aren't completely clear to me. I'm more used to using assign
in Javascript.
from addict.
Isn't assign part of ES6? I haven't played with it much, but I don't think it does a deep merge. I could be wrong.
from addict.
Related Issues (20)
- confuse with int HOT 1
- Is it possible to forbid accessing missing keys? HOT 4
- Dict adds quote when retrieving str values HOT 1
- Dict() inconsistent with dict() initialization HOT 4
- Adding support for merge operator `|` and `|=` (as python 3.9 dict merge) HOT 1
- Maintainership & Altrenatives HOT 4
- 'function' object has no attribute when using freeze as a field
- Dict.__missing__ implementation leads to surprising behaviour HOT 1
- google-colab 1.0.0 has requirement ipykernel~=4.10 HOT 1
- copy broken by 2.4.0 HOT 1
- Arrays in dictionaries, how to denote HOT 1
- Shouldn't dictionary keys be encapsulated with u''? Isn't everything in python 3 Unicode?
- Suggestion on attributes containing dashes
- Dict Attributes not available to Autocomplete and not present in __dict__ HOT 4
- have stubs for minimal type annotation on addict
- Somehow inherit from TypedDict
- Keys starting with __ can't be referenced with dotted notation inside an object
- Creating a Dict from instances of classes that inherit from NamedTuple
- Support inheritance in merge operators `|` and `|=`
- Consider changing the "About" line for this repo?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from addict.