简体   繁体   中英

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!

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'
}

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'}

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.

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'}

First, Try not to overwrite built-ins like str, list, etc.. with your variable/functions.

A simple way to do it:

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

my_dict = {}

for elt in some_elements:
    if "cat" in elt:
        my_dict[elt] = 'categorical'
    elif "num" in elt:
        my_dict[elt] = 'numerical'  

print(my_dict)

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

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'}

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'}
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)
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))))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM