Reputation: 41
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
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
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
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
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
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
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
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
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)
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.
{'cat1': 'categorical', 'cat2': 'categorical', 'cat3': 'categorical',
'number1': 'numerical', 'number2': 'numerical', 'number3': 'numerical'
}
Upvotes: 2