seb314
seb314

Reputation: 41

How do you use loop to assign dictionary value based upon key

I am trying to loop through a list used to create dictionary keys and assign a value based upon a few different categories

For example:

list = ['cat1', 'cat2', 'cat3', 'number1', 'number2', 'number3']

my_dict = {}

for i in range(len(list)):
     if any("cat" in s for s in list):
          my_dict[list[i]] = 'categorical'
     if any("num" in s for s in list):
          my_dict[list[i]] = 'numerical'  

I am trying to get a dictionary that would loop and result in:

my_dict = {'cat1': 'categorical', 'cat2': 'categorical', 'cat3': 'categorical', 'number1': 'numerical', 'number2': 'numerical', 'number3': 'numerical'}

Thanks for any help!

Upvotes: 4

Views: 132

Answers (8)

rajen
rajen

Reputation: 109

import itertools
lst = [‘cat1’, ‘cat2’, ‘cat3’, ‘number1’, ‘number2’, ‘number3’]
values = [‘categorical’, ‘numerical’]

dict(filter(lambda item: item[0][:3] == item[1][:3], list(itertools.product(lst, values))))

Upvotes: 0

user8864088
user8864088

Reputation:

The simplest answer:

l = ['cat1', 'cat2', 'cat3', 'number1', 'number2', 'number3', 'junk']
d = {k: 'categorical' if 'cat' in k else 'numerical' if 'number' in k else 'unknown' for k in l}

Output:

{'cat1': 'categorical', 'cat2': 'categorical', 'cat3': 'categorical', 'number1': 'numerical', 'number2': 'numerical', 'number3': 'numerical', 'junk': 'unknown'}

Upvotes: 0

U13-Forward
U13-Forward

Reputation: 71570

Try using the dictionary setdefault function:

l = ['cat1', 'cat2', 'cat3', 'number1', 'number2', 'number3']
my_dict = {}
for i in l:
    my_dict.setdefault(i,['numerical' if 'number' in i else 'category'][-1])  
print(my_dict)

Output:

{'cat1': 'category', 'cat2': 'category', 'cat3': 'category', 'number1': 'numerical', 'number2': 'numerical', 'number3': 'numerical'}

Upvotes: 0

Zev
Zev

Reputation: 3491

Your example is fairly close but has a few issues. Here is a solution that modifies your code as little as possible:

lst = ['cat1', 'cat2', 'cat3', 'number1', 'number2', 'number3']

my_dict = {}

for value in lst:
     if "cat" in value:
          my_dict[value] = 'categorical'
     if "num" in value:
          my_dict[value] = 'numerical'  

The first major issue is that you should never override a built-in. Use lst or list_ not list.

Now let's look at this bit of your code:

if any("cat" in s for s in lst):

...as you have it, this checks if "cat" appears anywhere in the list (not just in the item you meant to check).

Since this is true, 'cat1' would be assigned to categorical. But because you have another if statement that also evals to true for numerical, this result is overwritten and you end up with all of the entries being listed as numerical.

Upvotes: 0

cs95
cs95

Reputation: 402333

Stephen Rauch has a nice idea. Here's a slightly more concise version of what he's written using dict.get.

matches = {'num': 'numerical', 'cat': 'categorical'}
result = {k : matches.get(k[:3], 'unknown') for k in items}

print(result)
{'cat1': 'categorical',
 'cat2': 'categorical',
 'cat3': 'categorical',
 'number1': 'numerical',
 'number2': 'numerical',
 'number3': 'numerical'}

If you want to drop values that do not match, make a slight modification:

result = {k : matches[k[:3]] for k in items if k[:3] in matches}

Here's my take on it. Sort items first, and then find the index of discontinuity.

items.sort()

for i, l in enumerate(items):
    if l.startswith('num'):
        break

result = dict.fromkeys(items[:i], 'categorical')
result.update(dict.fromkeys(items[i:], 'numerical'))

This works best for two classes of values only.

print(result)
{'cat1': 'categorical',
 'cat2': 'categorical',
 'cat3': 'categorical',
 'number1': 'numerical',
 'number2': 'numerical',
 'number3': 'numerical'}

Upvotes: 2

Shashank Singh
Shashank Singh

Reputation: 657

list_ = ['cat1', 'cat2', 'cat3', 'number1', 'number2', 'number3']
# Don't name the variable "list" as it is a keyword if you can't think of anything else append a underscore at end

my_dict = {}

for item in list_:
    if "cat" in item:
        my_dict[item] = 'categorical'
    elif "number" in item:
        my_dict[item] = 'numerical'

print(my_dict)

Upvotes: 0

Austin
Austin

Reputation: 26039

Change your code a little bit; use startswith to look for a match:

lst = ['cat1', 'cat2', 'cat3', 'number1', 'number2', 'number3']

my_dict = {}

for x in lst:
    if x.startswith('cat'):
        my_dict[x] = 'categorical'
    elif x.startswith('num'):
        my_dict[x] = 'numerical'

print(my_dict)

# {'cat1': 'categorical', 'cat2': 'categorical', 'cat3': 'categorical', 'number1': 'numerical', 'number2': 'numerical', 'number3': 'numerical'}

Upvotes: 0

Stephen Rauch
Stephen Rauch

Reputation: 49784

If you can assume that values in your list will match one of your lookups, you can do that like:

items = ['cat1', 'cat2', 'cat3', 'number1', 'number2', 'number3']
matches = {'num': 'numerical', 'cat': 'categorical'}
result = {i: [v for k, v in matches.items() if k in i][0] for i in items}
print(result)

How?

This uses a dict to map the desired search string to a matched values. It then uses a loop comprehension to search each value in the dict and returns the matched value. The value is used as the value in the dict comprehension.

Results:

{'cat1': 'categorical', 'cat2': 'categorical', 'cat3': 'categorical',
 'number1': 'numerical', 'number2': 'numerical', 'number3': 'numerical'
}

Upvotes: 2

Related Questions