Jump to content

Function

erikpc43

Hello, i have a question about a function that I'm coding. I have a list that contains pairs like 

("Thomas", "pen"), ("Mike", "pencilcase"), ("Thomas", "rubber"), ("Tom", "scissors")

i would like to return a dictionary which keys would be the names of people and values should be everything the person "owns".

 

It should return a dictionary like this: 

{"Thomas": {"pen", "rubber"}, "Mike": {"pencilcase"}, "Tom": {"scissors"}}

 

What can i do here?

Edit: Im using python and i would like to write everyting in one line

Link to comment
Share on other sites

Link to post
Share on other sites

assuming you are using python, you could do something like this

 

from collections import defaultdict

d = defaultdict(set)
pairs = [("Thomas", "pen"), ("Mike", "pencilcase"), ("Thomas", "rubber"), ("Tom", "scissors")]
for name, item in pairs:
    d[name].add(item)
    
print(dict(d))

 

Link to comment
Share on other sites

Link to post
Share on other sites

Yes this is one way to do it. But i would really like to write everything in one line.

Link to comment
Share on other sites

Link to post
Share on other sites

9 minutes ago, erikpc43 said:

Yes this is one way to do it. But i would really like to write everything in one line.

Python compiler interpretor enforces indent so not possible. In java, everything can be squeeze into one line XD

Sudo make me a sandwich 

Link to comment
Share on other sites

Link to post
Share on other sites

2 minutes ago, wasab said:

Python compiler interpretor enforces indent so not possible. In java, everything can be squeeze into one line XD

Anything that can be written in Python can be written in 1 line, it might look silly sometimes though.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

58 minutes ago, fizzlesticks said:

Anything that can be written in Python can be written in 1 line, it might look silly sometimes though.

What are you going to use for indent?

Sudo make me a sandwich 

Link to comment
Share on other sites

Link to post
Share on other sites

#!/usr/bin/env python3

from itertools import groupby

l = [("Thomas", "pen"), ("Mike", "pencilcase"), ("Thomas", "rubber"), ("Tom", "scissors")]

d = dict((k, [v[1] for v in vs]) for (k, vs) in groupby(sorted(l), lambda x: x[0]))

print(d)
# {'Mike': ['pencilcase'], 'Thomas': ['pen', 'rubber'], 'Tom': ['scissors']}

Or from modifying @elpiop's solution:

#!/usr/bin/env python3

from collections import defaultdict

l = [("Thomas", "pen"), ("Mike", "pencilcase"), ("Thomas", "rubber"), ("Tom", "scissors")]

d = defaultdict(set);[d[name].add(item) for (name, item) in l]

print(dict(d))
# {'Thomas': {'rubber', 'pen'}, 'Mike': {'pencilcase'}, 'Tom': {'scissors'}}
Edited by mshaugh
Added one-liner for @elpiop's solution
Link to comment
Share on other sites

Link to post
Share on other sites

2 hours ago, wasab said:

What are you going to use for indent?

You use things that don't need indenting. For example here's elpiops answer in 1 line:

print(dict((lambda d: (d, [d[name].add(item) for name, item in [("Thomas", "pen"), ("Mike", "pencilcase"), ("Thomas", "rubber"), ("Tom", "scissors")]])[0])(__import__('collections').defaultdict(set))))

 

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

7 minutes ago, fizzlesticks said:

You use things that don't need indenting. For example here's elpiops answer in 1 line:


print(dict((lambda d: (d, [d[name].add(item) for name, item in [("Thomas", "pen"), ("Mike", "pencilcase"), ("Thomas", "rubber"), ("Tom", "scissors")]])[0])(__import__('collections').defaultdict(set))))

 

But what are you going to use to write a function? 

Sudo make me a sandwich 

Link to comment
Share on other sites

Link to post
Share on other sites

42 minutes ago, wasab said:

But what are you going to use to write a function? 

Lambdas mostly.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

....why does this need to be 1 line? That's usually pretty bad codesmanship. Super complex one line statements might seem clever, but you get no performance benefit from it and it usually only makes things harder to maintain.

 

Good code is finding ways to be elegant and performant, all while also being easy to read, test, and maintain. Trying to find cheeky ways to crunch 4-5 lines into 1 PROBABLY isn't going to be "good" (though as always, there are exceptions)

Note, I don't write python professionally, so maybe there is some language standard i'm ignoring, but in a general software engineering sense this:

d = defaultdict(set)
pairs = [("Thomas", "pen"), ("Mike", "pencilcase"), ("Thomas", "rubber"), ("Tom", "scissors")]
for name, item in pairs:
    d[name].add(item)
    
print(dict(d))

is far better than:

print(dict((lambda d: (d, [d[name].add(item) for name, item in [("Thomas", "pen"), ("Mike", "pencilcase"), ("Thomas", "rubber"), ("Tom", "scissors")]])[0])(__import__('collections').defaultdict(set))))

And unless there is some python specific reason, I wouldn't let the 2nd example through code review. Sure it's not that hard to figure out what's going on, but why make the people maintaining this code have to go through even simple puzzles to figure out what your code is doing? What's the advantage of getting this all onto 1 line? The easier you make it for others to understand your code, the less chance a defect gets introduced. This is the same issue I have with list comprehensions that get too crazy, or when `auto` is abused in C++ to use a non-python example.

Gaming build:

CPU: i7-7700k (5.0ghz, 1.312v)

GPU(s): Asus Strix 1080ti OC (~2063mhz)

Memory: 32GB (4x8) DDR4 G.Skill TridentZ RGB 3000mhz

Motherboard: Asus Prime z270-AR

PSU: Seasonic Prime Titanium 850W

Cooler: Custom water loop (420mm rad + 360mm rad)

Case: Be quiet! Dark base pro 900 (silver)
Primary storage: Samsung 960 evo m.2 SSD (500gb)

Secondary storage: Samsung 850 evo SSD (250gb)

 

Server build:

OS: Ubuntu server 16.04 LTS (though will probably upgrade to 17.04 for better ryzen support)

CPU: Ryzen R7 1700x

Memory: Ballistix Sport LT 16GB

Motherboard: Asrock B350 m4 pro

PSU: Corsair CX550M

Cooler: Cooler master hyper 212 evo

Storage: 2TB WD Red x1, 128gb OCZ SSD for OS

Case: HAF 932 adv

 

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×