How to Handle Multiple Keys for a Dictionary in Python

How to handle multiple keys for a dictionary in python?

defaultdict/dict.setdefault

Let's jump into it:

  1. Iterate over items consecutively
  2. Append string values belonging to the same key
  3. Once done, iterate over each key-value pair and join everything together for your final result.
from collections import defaultdict

d = defaultdict(list)
for i, j in zip(list_1, list_2):
d[i].append(j)

The defaultdict makes things simple, and is efficient with appending. If you don't want to use a defaultdict, use dict.setdefault instead (but this is a bit more inefficient):

d = {}
for i, j in zip(list_1, list_2):
d.setdefault(i, []).append(j)
new_dict = {k : ','.join(v) for k, v in d.items()})
print(new_dict)
{'4': 'a', '6': 'b', '8': 'c,d'}

Pandas DataFrame.groupby + agg

If you want performance at high volumes, try using pandas:

import pandas as pd

df = pd.DataFrame({'A' : list_1, 'B' : list_2})
new_dict = df.groupby('A').B.agg(','.join).to_dict()

print(new_dict)
{'4': 'a', '6': 'b', '8': 'c,d'}

Creating multiple keys dictionaries from lists

This should give you the result you need using a dictionary comprehension:

Demand_dict = {(p, c): d for p, c, d in zip(Product, Client, Demand)}

It zips the three lists and then iterates over the 3-tuples using the first two values as the key for a dictionary entry and the third value as the value.

Python - create dictionary with multiple keys and where value is also dictionary

you could just do this:

test = {"11.67": 1, "12.67": 2}
res = {key: {"value": str(int(float(key)))} for key in test}
# {'11.67': {'value': '11'}, '12.67': {'value': '12'}}

where i first convert the strings to floats, then discard the fractional part by using int and convert back to str again.

what goes wrong in your code is nicely explained in Carsten's answer.

multiple keys and values in python dictionary

Firstly, you have to be able to get the text output from the app shown in the picture, then you use your dictionary to check it.

And the way to design the dictionary makes it difficult to check. You should design it that way: key is only one string, and values is a list. For example:

Dic = {"A": ["od"], "ab": ["od"], "Acutus": ["Akuten", "Akutna", "Akutno"], "Aromaticus": ["Dišeč", "Odišavljen"]}

So now after you get the text from your app, let's say it is text = 'ab:id'. You will split it to key and value then check in your dict:

def check(text):
text = text.split(':')
key = text[0]
value = text[1]
if value in Dic[key]:
return True
return False

Let's try it out

>>> check('ab:id')
False
>>> check('ab:od')
True
>>> check('Acutus:Akutna')
True
>>> check('Acutus:Akutno')
True

is there a faster way to get multiple keys from dictionary?

You could use:

>>> list(map(d.get, l))
[1, 2, None]

It has two advantages:

  • It performs the d.get lookup only once - not each iteration
  • Only CPython: Because dict.get is implemented in C and map is implemented in C it can avoid the Python layer in the function call (roughly speaking the details are a bit more complicated).

As for timings (performed on Python 3.6 in a Jupyter notebook):

d = {'a':1, 'b':2, 'c':3, 'd':4}
l = ['a', 'b', 'z']

%timeit list(map(d.get, l))
594 ns ± 41.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit [d.get(k) for k in l]
508 ns ± 17.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Note that this is actually slower in this case! That's because for short iterables the map and list overhead dominate. So if you want it faster on short iterables stick with your approach.

With longer l you see that list(map(...)) eventually becomes faster:

d = {'a':1, 'b':2, 'c':3, 'd':4}
l = [random.choice(string.ascii_lowercase) for _ in range(10000)]

%timeit list(map(d.get, l))
663 µs ± 64.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit [d.get(k) for k in l]
1.13 ms ± 7.55 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

However that's still "just" a factor of 2 faster.

Dictionary with multiple keys mapping to same value

Is it what you want to achieve ?

int_dict = { 0              : "String1",
1 : "String2",
2 : "String3",
16 : "String5" };
#range is first inclusive last exlusif, watch out for that
for i in range(3,15) :
int_dict[i] = "String4"

output :

{0: 'String1',
1: 'String2',
2: 'String3',
3: 'String4',
4: 'String4',
5: 'String4',
6: 'String4',
7: 'String4',
8: 'String4',
9: 'String4',
10: 'String4',
11: 'String4',
12: 'String4',
13: 'String4',
14: 'String4',
16: 'String5'}

Edit : you can also use tuple as key

int_dict = { (0,0)              : "String1",
(1,1) : "String2",
(2,2) : "String3",
(3,15) :"String4",
(16,16) : "String5"};

def ValueInDict(value):
for i,j in int_dict.items():
if value >= i[0]:
if value <= i[1]:
print(j)
return
print("NOT THERE")

ValueInDict(5)

ouput :

 String4


Related Topics



Leave a reply



Submit