Python Dictionary Aggregation??
Vložit
- čas přidán 3. 09. 2023
- ⭐ Join the Byte Club to practice your Python skills! ($2.99/mo): / @b001
🐦 Follow me on Twitter: / b001io
Background Music:
Gentle Lo-Fi Vlog Background Music | Cookies by Alex-Productions | onsound.eu/
Music promoted by www.free-stock-music.com
Creative Commons / Attribution 3.0 Unported License (CC BY 3.0)
creativecommons.org/licenses/...
python just keeps throwing more niche and actually useful stuff at me the longer i study it
in R these would be data.frames and this would be more cognitively straight forward
@vow4n I have a strong suspicion that all these guys who obviously have a strong urge to write comments everywhere, all the time, where they try to imply that they are experienced rust developers, actually suffering from microphallus.
That’s really cool. As someone who’s beginning to learn python the way you weight it so smoothly is nice
Would recommend reading python for everybody
How did you understand really still confusing to me
I didn't even know that dictionary comprehension even existed
Same, I only knew generator and list comprehensions up until this
As a senior programmer, this is a beautiful explanation. Thank you for this.
And the fact that a senior programmer has nothing to say about this terrible code proves how doomed programming jobs are
I think this CZcams short just saved my life
Counter. Use Counter. It's in the stdlib
from collections import Counter
No need to use sets, it's simpler and faster to:
for key in loot:
inv[key] = inv.get(key, 0) + loot[key]
Do let me know if there are any problems with this
And it should be faster, cause we got rid of union operator and conversion to set.
This modifies inv inplace instead of creating a new dictionary. However, I actually expect this to be the better behavior than what is shown in the short.
A small thing to improve in your code is to use `for key, amount in loot.items()` instead of accessing `loot[key]` inside of the loop body.
Right, I may have missed the point. Maybe they were trying to avoid using dict.copy().
Is using .items() more time efficient? I didn't know that, thanks
This raise problem when there is key in inv but not in loot.
@@ahmadfahadhilyas no, it does not. Test it.
List and Dictionary comprehension is one of my favorite parts of python. Thats the reason why I opt to use python for quick scripting over Lua sometimes
A great trick to make the next developer think far longer about a simple algorithm than necessary. It's like pranking your future self.
This is so elementary that even Sherlock Holmes wouldn't bother to investigate it.
did my future self forget how to read syntax
@@bitzero000 If you think it's a good idea, then go ahead and see for yourself where it leads to. 🙂
Or just don't forget python concepts 🤷
@@DoubleBob It's like learning idiom on top of the previous old idiom, which is also on top of the previous previously old idiom.
Cool I’m still gonna use the for loop
A neat use for dictionary comprehension! It’s something I’ve always known existed but never touched because I didn’t need it
If you are making an inventory - it might be better to iterate through loot only instead of your whole inventory
Can you explain through a code please?
@@exxology1No need for a code
Inventory may contain all keys in the game
Loot will only contain a select few items, if it's referring to someone opening a container
Therefore (except when inventory is empty), iterating over the loot object is always faster than iterating over the inventory
While I love the conciseness of this, I never end up using such complex comprehensions when writing code as it makes it virtually unreadable. While this only takes two lines, I would much prefer writing a for loop that would take six or seven that is easier on the eyes, lol.
Keep up the great content
Im on the totally opposite side of the barricades here.
I use comprehensions whenever possible instead of unnested loops.
The readability is in the eye of the beholder, but i do enjoy turning 3 lines into one and avoiding extra indentations and that i never need to care about those k,v variables.
It makes more sense to write these in a helper function.
No need for a loop or a helper function. Use Counter from collections, this problem has already been solved
The simple solution you're advocating would be understood by any programmer. The pythonic solution is only understood by people who write python a lot.
Keep writing code your way. The rest of us who haven't drunk the pythonic koolaid will thank you.
That's a terrible take. Not only are comprehensions just as easy to understand (if not more) than for loops, but advocating for less "pythonic" solutions in deference to other programmers basically implies that all programming languages should be the same and that you should never learn anything new.
In Clojure you would do a much more simple `(merge-with + inv loot)`
Like the use of set to ensure you get the aggregate of both dictionaries in the output.
set(inv | loot) seems improper because if you try that type of expression by itself you will get undefined operation | for dict. In fact it doesn't work at all for me in python 3..8; did you change the code and not update the video ? I needed to do "set(inv.keys() | loot.keys())"
The backslash is not required between brackets
it is, because that is one expression split across multiple lines. Backslashes arent required when each line is one element in the dictionary
@insertcreativenamehere492 it's not, try it for yourself. For example, this is perfectly valid:
x = [
i
for i in range(10)
if not i % 2
]
You don't even need indentation if it's in a comprehension
@@schlopping my bad, I thought OP was talking about style guidelines. Yeah, that's technically valid code, but I would probably still add the backslashes for clarity
@insertcreativenamehere492 Got it, thanks for clearing that up. Regardless I wouldn't add them since PEP-8 and most style guides heavily discourage backslashes, though as always, your personal preference is the most important
Loved this video. Thanks a lot!
Your videos are so CRAZY EXCELLENT for us bro!! I enjoy and learn so much especially the ones you teach about GAMING RPG like this!!!! Like RPG codes like this is what made me subscribe and notifications+ on you hahaha😂
Its incredible reading comments on these videos and seeing everyone forget that your allowed to comment code to explain things
I love ur short videos
That’s great, but why the set operation?
This man need a raise , keep high bruh ❤❤❤
Turning my feed into programming stuff only les gooo
Wish i could bookmark this short
You can
you can save it bruh
I believe if you’re in a smartphone, the top right 3 vertical dots should allow you to save these shorts.
@@The.Truth13thank you!! Appreciate you for taking the extra minute to explain. I never realized I could save shorts either and I probably wouldn’t have bothered looking for how to lol
@@exxology1 it’s all good I gotcha💪🏽
A cool way to extract quickly add the loot too your inv!
Or:
from collections import Counter
print(Counter(inv) + Counter(loot))
`from collections import Counter; Counter(inv) + Counter(loot)`
This is very useful!!!
Can you delve deeper into dict comprehension???
I want to learn more about it
Try a defaultDict from the collections module for the inventory!
Thats why we have table.insert in lua. You can just do a for loop with all indexes of the lst and insert the value in it
May God bless, very nice and helpful reference!
This is very cool. Thanks for this. :)
Would love to have all these examples in example scripts I just unzip on my raspberry pi to refer to as and when needed
Set on dict keys - i didn't know that
Really creative!! 👏
Use Counter it’s fast too!
Never knew about that union operation
I appreciate that none of this is really unique to python apart from the syntax being clean
As someone who peaked with writing a program which spits out the Fibonacci sequence in java script, cool.
Man this makes me miss php
Or just use Counter, looks way better and can be used in many other places.
from collections import Counter
inventory = Counter(inv)
inventory.update(loot)
Super cool, I would suggest maybe first storing the unique keys in a variable before the list comprehension rather than using set through each iteration
The set is only initialized once so no problem there 😀
Can we use conuter from collections ?
Yes. You can simply add two Counters together, and it'll do the multi-set merge for you.
You don't need to use set()
How I would do it based on your style:
merge = lambda x, y: {k:x.get(k, 0)+y.get(k,0) for k in x | y}
inv = {'s':1,'p':2}
chest = {'s':1,'p':3,'sh':1}
inv = merge(inv, chest)
print(inv)
And if ChainMap from collections suits this exercise??
@@blenderpanzi ChainMap is about another purpose, but still can be applied if you have more than 2 dictionaries. Your way of dictionary comprehension is appealing to me :)
This violates PEP8.
So, I want next video to be about dropping some items. 😂
Use the counter from collections instead
I found another method using a loop and not creating a new dictionary:
for key in dict2.keys():
dict2[key] += dict1.get(key, 0)
This will work only if you know the largest dictionary.
Couldnt you just create an empty dictionary then do a for loop through each dictionary and merge them together?
Would be much more readable
no it has to be this way
result = \
{
key: value + inv.get(key, 0)
for key, value in loot.items()
}
this will miss key that are in inv but not in loot
@@rkdeshdeepak4131 thanks for the comment a bit rusty on my python since I have not used it for years, had to solve this today thanks to you :D
this will add regardless of how many items(keys) in both inv and loots are missing in each other.
# dummy datas
inv = {
"Sword": 1,
"Potion": 3,
"Spear": 2,
"Poison": 5,
"Keys": 5,
"Gears": 20,
"medicine": 14
}
loot = {
"Sword": 1,
"Potion": 2,
"Shield": 1,
"Technology": 3,
"Poison": 6,
"Armaments": 14
}
# decorator
def find_missing_keys(fn):
def wrapper(inv, loot, *args, **kwargs) -> tuple:
x, y = set(inv), set(loot)
difference = tuple(x.difference(y))
return fn(difference, *args, **kwargs)
return wrapper
# main func
@find_missing_keys
def combined_inventories(
missing_keys: tuple,
inv: dict = inv,
loot: dict = loot
) -> dict:
combined_dict = {}
for item in missing_keys:
if inv.get(item):
new_item = inv.get(item)
combined_dict[item] = new_item
if loot.get(item):
new_item = loot.get(item)
combined_dict[item] = new_item
res = { k: v + inv.get(k, 0) for k, v in loot.items() }
combined_dict.update(res)
return combined_dict
print(combined_inventories(inv, loot))
No, I'd rather just loop through the .keys() of each dictionary and use that to create a new one. It's more about readability and this method you're showing is not easy to read
What if inv and loot are not listed in the same item order?
Can anyone explain how the set(inv | loot) in the for-loop works?
In his example, he uses set() to deduplicate the keys from inv and loot so they are only processed once.
Could you declare the for loop before the k useage?
Would like a slower video explaining this 😅
He really need to and take time to explain syntax to be understable easily
seems like a java arraylist but with common property index?
Julia can do this in a clean one-line: merge(+, inv, loot)
You can use any function to apply to each duplicate (key, value) pair as the first argument
Hey can you add captions somehow. I really love your videos but I am not good in English.
Kotlin version (just out of boredom):
(inv.keys + loot.keys).associateWith { (inv[it] ?: 0) + (loot[it] ?: 0) }
Nice to save some lines of code, but pythons main goal of readability is not achieved.
That’s what comments are for!
CZcams comments? Yes. Coding Comments? No. Code readability is not achieved by comments but by clear, structured and human-readable coding.
Dictionary comprehension is also faster than regular loops.
@@PogoDigitalismi always say if you are that concerned about speed then python is not your language.
@@shrayesraman5192 very true haha
Is there longer vid about it
Dict/list comprehension are amazing ! Just be mindful of when to use them.Putting complex logic inside a comprehension makes the code less readable and hard to comprehend.
(Think twice, if the logic that you are using to build the list/dict spans across multiple lines )
Why not use just Counter?
If you have a very large list that would be a performance issue
Came here for this. Nothing mind blowing about this video...
How to convert date into string and retrieve back to date
Feels inefficient compared to just iterating through one of the lists. May not matter if the dictionaries are small, but I wouldn't say this is particularly readable compared a for loop.
How does the text just come
What is your vscode theme?????? I NEED to know
SynthWave’84
And font please?
How we do that without any inbuilt operator??
Not a PyDev anymore but this is cool
you don’t need a backslash
Could you please explain on k: ?
Awesome dude. Very useful 😊 especially in some django projects
from collections import Counter
new_inv = Counter(inv) + Counter(loot)
new_inv = dict(new_inv) # optional
Done.
Why not just `combined = inv | loot`?
Sick!
4k in set(inv | loot
😂😂
Just use collections.Counter.
How about using reduce function
What python IDE are you using? Looks really clean. Wanne use it
Vs Code
Good one! How we can do the same with list of dictionaries.??
l = [{"a":1},{"b":2}]
x = {k:v for d in l for k, v in d.items()}
print(x)
You can have multiple layers of unnesting in a comprehension like you would in a normal loop.
May you live long.
this should be a built-in python function.
it is. there is a dict subclass in the 'collections' module called Counter that does this
or simpler:
z = x | y
on python 3.9+
did you watch the video?
Doesn’t satisfy the requirements.
huh, I had no idea "|" worked on dicts
or just update a collections.Counter
How do you just paste the code like that?
Union operator hurts
good stuff
what's the "\" for?
Usually, it’s to say that the line continues to the next line. Here, it was completely unnecessary.
A bit late but can someone explain the code to me a bit more? Especially the last part
bro, which font are you using?
Bro which theme is this?
Which software do you use?
how I can save mine of gold?
Hi what theme do you use ?
Im so confused about the "|" operator, i have no idea how it works
It’s basically the .update method. It combines the two dictionaries and updates the values of same keys
@@Darkev77 ok thanks, but I also see it used in examples like
i = 7 | 9
print(i)
and the output is 15, how does that work?
I've never seen anyone use it personally TBH, but "|" is used to perform a bit-wise OR. So if you take the binary representation of 7 and 9, then perform bit-wise OR, you get 15.@@thesalvagedgamer4076
@@thesalvagedgamer4076 if operators are integers , then it works like bitwise or
0111 = 7
1001 = 9
---------------- Bitswise OR ( | )
1111 = 15
Functionality of any operator depends on operands.
For sets it works as union, gives union of two sets.
For dictionary it is similar, creates a new dict with all key val pair in both dict, the right having a precedence , if same key is in both.
Whats that font?
So cool 🔥🔥
TypeError: unsupported operand type(s) for |: 'dict' and 'dict' -- currently what I'm getting for line 12
I think you are using a python interpreter version that doesn't support the operator '|'
Alternatively you can unpack both dictionaries in a new one, then in the 'set' try something like this: set({**inv, **loot})
which version of python are you using?
Can anyone explain me how that happens pls im new to this