I am trying to create new variables depending on how many elements are stored inside a list.
It would have to look something like this:
dict = {}
list = [1, 2, 3, 4]
for obj in list:
if obj not in dict:
dict[obj] = var + obj = None
How do I do this?
You could do something like this:
>>> l = [1, 2, 3, 4]
>>> d = {'var%d' % el: None for el in l}
>>> d
{'var4': None, 'var1': None, 'var3': None, 'var2': None}
If you want to add new item in dictionary using value from list as a key, you can try this
dict[obj] = new_value
You can use the constructor classmethod dict.fromkeys to pre-add any number of keys to a dictionary:
d = dict.fromkeys(f'var{x}' for x in lst)
OR
d = dict.fromkeys(map('var{}'.format, lst))
Please don't use the variable names dict and list. They overwrite the built-in names in your names, so you won't be able to use the built-in classes until you do del list and del dict.
Here is an example with a longer list with some duplicates:
myDict = {}
myList = [1, 2, 3, 4, 3, 2, 8, 1]
for obj in myList:
if obj not in myDict:
myDict["var" + str(obj)] = None
The output is:
myDict {'var1': None, 'var2': None, 'var3': None, 'var4': None, 'var8': None}
Related
Im trying to print specific value in this dictionary compiled of several list.
the_dic = {'k1':[1,2,3,{'tricky':['oh','man','inception',{'target':[1,2,3,'hello']}]}]}
Expected output: hello
Can i expand from this simple code below?
print(the_dic["k1"])
You can keep indexing further by referring to the specific index (of the list) [3] or further keys in the dictionary!
This works because the result of each indexing or key reference returns the inner value, which exposes its own methods for indexing or referring to its keys (or a single value, ending your chain!) depending on the inner type
Continuing the chain little further
>>> d = {'k1':[1,2,3,{'tricky':['oh','man','inception',{'target':[1,2,3,'hello']}]}]}
>>> d["k1"]
[1, 2, 3, {'tricky': ['oh', 'man', 'inception', {'target': [1, 2, 3, 'hello']}]}]
>>> d["k1"][3]
{'tricky': ['oh', 'man', 'inception', {'target': [1, 2, 3, 'hello']}]}
>>> d["k1"][3]["tricky"]
['oh', 'man', 'inception', {'target': [1, 2, 3, 'hello']}]
Offering a simpler example, it may be clearer still
>>> d = {'a': {'b': [1,2,3]}}
>>> d['a']['b'] # list referenced by key 'b' within key 'a' of d
[1, 2, 3]
>>> d['a']['b'][0] # first member of the very innermost list
1
I think for your desired output your final code will be:
the_dic = {'k1':[1,2,3,{'tricky':['oh','man','inception',{'target':[1,2,3,'hello']}]}]}
print(the_dic['k1'][3]['tricky'][3]['target'][3])
Result:
hello
A helper recursive function such as this should do the trick:
def get_last_val(d):
if isinstance(d, list):
return get_last_val(d[-1])
if isinstance(d, dict):
return get_last_val(d.popitem()[1])
return d
Example:
>>> get_last_val(the_dic)
'hello'
I quite regularly want to create a dictionary where keys are variable names. For example if I have variables a and b I want to generate: {"a":a, "b":b} (typically to return data at the end of a function).
Are there any (ideally built in) ways in python to do this automatically? i.e to have a function such that create_dictionary(a,b) returns {"a":a, "b":b}
Have you considered creating a class? A class can be viewed as a wrapper for a dictionary.
# Generate some variables in the workspace
a = 9; b = ["hello", "world"]; c = (True, False)
# Define a new class and instantiate
class NewClass(object): pass
mydict = NewClass()
# Set attributes of the new class
mydict.a = a
mydict.b = b
mydict.c = c
# Print the dict form of the class
mydict.__dict__
{'a': 9, 'b': ['hello', 'world'], 'c': (True, False)}
Or you could use the setattr function if you wanted to pass a list of variable names:
mydict = NewClass()
vars = ['a', 'b', 'c']
for v in vars:
setattr(mydict, v, eval(v))
mydict.__dict__
{'a': 9, 'b': ['hello', 'world'], 'c': (True, False)}
You can write your own function for create_dict
def create_dict(*args):
return dict({i:eval(i) for i in args})
a = "yo"
b = 7
print (create_dict("a", "b"))
Which gives {'a': 'yo', 'b': 7} output.
Here's a simple generator for the same:
vars = ["a", "b"]
create_dict = {i:eval(i) for i in args}
or you can use this one-liner lambda function
create_dict = lambda *args: {i:eval(i) for i in args}
print (create_dict("a", "b"))
But if you want to pass the variables to the function instead of the variable name as string, then its pretty messy to actually get the name of the variable as a string. But if thats the case then you should probably try using locals(), vars(), globals() as used by Nf4r
Extending on the code of #Nf4r, I use something like:
a, b = 1, 2
def make_dict(*args):
# Globals will change of size, so we need a copy
g = {k: v for k, v in globals().items() if not k.startswith('__')}
result = {}
for arg in args:
for k, v in g.items():
try:
if v == arg:
result[k] = v
except ValueError:
continue # objects that don't allow comparison
return result
make_dict(a, b)
Have you tried something like:
a, b, c, d = 1, 2, 3, 4
dt = {k:v for k, v in locals().items() if not k.startswith('__')}
print(dt)
{'a': 1, 'd': 4, 'b': 2, 'c': 3}
I have a for loop which is going through multiple dictionaries and adding the values under common keys. The input dictionary has keys that are strings and values that are int's. For some reason its adding the values as lists of one value (e.g. {"01":[12],[44]}). I want it to add the int on its own but cant get that working for some reason. I'm using the code below, is there something i am missing ?
dw = defaultdict()
dw = {}
for key, value in listb.items():
dw[key].append(value)
If you want to forgo all good practice and not use defaultdict(list), you can use setdefault and call it every single time you choose to add a value. This is inefficient and not idiomatic, but it will work.
In [1]: from collections import defaultdict
In [2]: a = defaultdict(list)
In [3]: b = {}
In [4]: a[1].append(1)
In [5]: b.setdefault(1, []).append(1)
In [6]: a
Out[6]: defaultdict(list, {1: [1]})
In [7]: b
Out[7]: {1: [1]}
In [8]:
As long as the values in the dicts are ints (not lists):
dw = {}
for key, value in listb.items():
try: # Key exists in dictionary and value is a list
dw[key].append(value)
except KeyError: # Key does not yet exist in dictionary
dw[key] = value
except AttributeError: # Key exist in dictionary and value is not a list
dw[key] = [dw[key], value]
If you mean to add key/value pairs to the dictionary (and not append to an array), it's:
for key, value in listb.items():
dw[key] = value
EDIT: or is it something like this you're after?
listb = {'1': 3, '2': 5}
dw = {'1': 5, '2': 9}
for key, value in listb.items():
if key not in dw.keys():
dw[key] = []
else:
dw[key] = [dw[key]]
dw[key].append(value)
which gives dw = {'2': [9, 5], '1': [5, 3]}
If you have a list like listb = [{'a': 1, 'b': 2}, {'a': 3, 'b': 4, 'c': 5}, {'b': 1}], you can try this:
dw = {}
for d in listb:
for k, v in d.items():
if k in dw:
if isinstance(dw[k], list):
dw[k].append(v)
elif isinstance(dw[k], int):
dw[k] = [dw[k], v]
else:
dw[k] = v
print(dw)
{'a': [1, 3], 'b': [2, 4, 1], 'c': 5}
>>>
My list is something like this,
['"third:4"', '"first:7"', '"second:8"']
I want to convert this into a dictionary like this...
{"third": 4, "first": 7, "second": 8}
How do I do this in Python?
Here are two possible solutions, one that gives you string values and one that gives you int values:
>>> lst = ['"third:4"', '"first:7"', '"second:8"']
>>> dict(x[1:-1].split(':', 1) for x in lst)
{'second': '8', 'third': '4', 'first': '7'}
>>> dict((y[0], int(y[1])) for y in (x[1:-1].split(':', 1) for x in lst))
{'second': 8, 'third': 4, 'first': 7}
However, for the sake of readability, you could split the conversion into two steps:
>>> lst = ['"third:4"', '"first:7"', '"second:8"']
>>> dct = dict(x[1:-1].split(':', 1) for x in lst)
>>> {k: int(v) for k, v in dct.iteritems()}
Of course this has some overhead since you create a dict twice - but for a small list it doesn't matter.
>>> data
['"third:4"', '"first:7"', '"second:8"']
>>> dict((k,int(v)) for k,v in (el.strip('\'"').split(':') for el in data))
{'second': 8, 'third': 4, 'first': 7}
or
>>> data = ['"third:4"', '"first:7"', '"second:8"']
>>> def convert(d):
for el in d:
key, num = el.strip('\'"').split(':')
yield key, int(num)
>>> dict(convert(data))
{'second': 8, 'third': 4, 'first': 7}
def listToDic(lis):
dic = {}
for item in lis:
temp = item.strip('"').split(':')
dic[temp[0]] = int(temp[1])
return dic
With map and dict it is very straight forward.
syntax for map
map(func, iterables)
to_dict will return key, value which will be consumed by dict
def to_dict(item):
return item[0].replace('"',''), int(item[1].replace('"', ''))
>>> items
6: ['"third:4"', '"first:7"', '"second:8"']
>>> dict(map(to_dict, [item.split(':') for item in items]))
7: {'first': 7, 'second': 8, 'third': 4}
help(dict)
class dict(object)
dict() -> new empty dictionary
dict(mapping) -> new dictionary initialized from a mapping object's
(key, value) pairs
dict(iterable) -> new dictionary initialized as if via:
d = {}
for k, v in iterable:
d[k] = v
dict(**kwargs) -> new dictionary initialized with the name=value pairs
in the keyword argument list. For example: dict(one=1, two=2)
Final Code
>>> dict(map(to_dict, [item.split(':') for item in items]))
how join list tuple and dict into a dict?
['f','b','c','d'] (1,2,3) and {'a':'10'}
d excluded for list be compatible with the tuple
output {'f':'1','b':'2','c':'3','a':'10'}
You can make a dict from keys and values like so:
keys = ['a','b','c','d']
values = (1,2,3)
result = dict(zip(keys, values)) # {'a': 1, 'c': 3, 'b': 2}
Then you can update it with another dict
result.update({ 'f' : 5 })
print result # {'a': 1, 'c': 3, 'b': 2, 'f': 5}
dict(zip(a_list, a_tuple)).update(a_dictionary)
when a_list is your list, a_tuple is your tuple and a_dictionary is your dictionary.
EDIT:
If you really wanted to turn the numbers in you tuple into strings than first do:
new_tuple = tuple((str(i) for i in a_tuple))
and pass new_tuple to the zip function.
This will accomplish the first part of your question:
dict(zip(['a','b','c','d'], (1,2,3)))
However, the second part of your question would require a second definition of 'a', which the dictionary type does not allow. However, you can always set additional keys manually:
>>> d = {}
>>> d['e'] = 10
>>> d
{'e':10}
The keys in a dictionary must be unique, so this part: {'a':'1','a':'10'} is impossible.
Here is code for the rest:
l = ['a','b','c','d']
t = (1,2,3)
d = {}
for key, value in zip(l, t):
d[key] = value
Something like this?
>>> dict({'a':'10'}.items() + (zip(['f','b','c','d'],('1','2','3'))))
{'a': '10', 'c': '3', 'b': '2', 'f': '1'}
Since noone has given an answer that converts the tuple items to str yet
>>> L=['f','b','c','d']
>>> T=(1,2,3)
>>> D={'a':'10'}
>>> dict(zip(L,map(str,T)),**D)
{'a': '10', 'c': '3', 'b': '2', 'f': '1'}
>>> l = ['a','b','c','d']
>>> t = (1,2,3)
>>> d = {'a':'10'}
>>> t = map(str, t) # the OP has requested str values, let's do this first
If you are OK with mutating the original dict, then you can just do this:
>>> d.update(zip(l, t))
or in Python 3.9+ (PEP 584):
>>> d |= zip(l, t)
But if you need to keep the original d intact:
>>> new_d = dict(zip(l, t))
>>> new_d |= d