How can i assign multiple keys the same value | python - python

In Python, how can we assign multiple dictionary keys the same value.
I tried something below but it's not working.
server = {'server1','server2': 'abc#xyz.com', 'server3','server4':'pqr#xyz.com'}

For example:
s = "the_value" # the value you want for the keys below
l = ["name", "age", "address"] # keys
d = {} # initiating an empty dictionary
for item in l:
d[item] = s
This should print
{'name': 'the_value', 'age': 'the_value', 'address': 'the_value'}

If you order your inputs as list of tuples, where each tuple is the value and a list of servers, you can use a nested list comprehension to create your dictionary:
from pprint import pprint
# arange your inputdata as tuples of ("value" to be set, list of servers)
# data = [ (f"login_{v}",[f"server_{v}{10+w}" for w in range(3)]) for v in range(5)]
data = [ ('login_0', ['server_010', 'server_011', 'server_012']),
('login_1', ['server_110', 'server_111', 'server_112']),
('login_2', ['server_210', 'server_211', 'server_212']),
('login_3', ['server_310', 'server_311', 'server_312']),
('login_4', ['server_410', 'server_411', 'server_412']) ]
# create the dict using a nested list comprehension
d = {k:v for v,keys in data for k in keys}
pprint(d)
Output:
# of the created dict using a nested list comprehension
{'server_010': 'login_0',
'server_011': 'login_0',
'server_012': 'login_0',
'server_110': 'login_1',
'server_111': 'login_1',
'server_112': 'login_1',
'server_210': 'login_2',
'server_211': 'login_2',
'server_212': 'login_2',
'server_310': 'login_3',
'server_311': 'login_3',
'server_312': 'login_3',
'server_410': 'login_4',
'server_411': 'login_4',
'server_412': 'login_4'}
See Explanation of how nested list comprehension works? if you do not know about those.

You could use tuples as keys but then it is difficult to find the dictionary entry corresponding to a single value
server = {('server1','server2','serverX'): 'abc#xyz.com', \
('server3','server4'):'pqr#xyz.com'}
Note: you can do that because tuples are hashable.
This makes only sense if you want to query the dictionary by exactly such tuples, for instance:
server[('server3', 'server4')]
# Out: 'pqr#xyz.com'

Related

Sort python list into dictionary of lists, based on property in list

I'm trying to sort a list of objects in python into a dictionary of lists via a property of the objects in the original list
I've done it below, but this feels like something I should be able to do using a dictionary comprehension?
for position in totals["positions"]:
if not hasattr(totals["positions_dict"], position.get_asset_type_display()):
totals["positions_dict"][position.get_asset_type_display()] = []
totals["positions_dict"][position.get_asset_type_display()].append(position)
Some self improvements
totals["positions_dict"] = {}
for position in totals["positions"]:
key = position.get_asset_type_display()
if key not in totals["positions_dict"]:
totals["positions_dict"][key] = []
totals["positions_dict"][key].append(position)
You could use itertools.groupby and operator.methodcaller in a dict comprehension:
from operator import methodcaller
from itertools import groupby
key = methodcaller('get_asset_type_display')
totals["positions_dict"] = {k: list(g) for k, g in groupby(sorted(totals["positions"], key=key), key=key)}
Using a defaultdict as suggested by #Jean-FrançoisFabre allows you to do it with a single call to get_asset_type_display() in one loop:
from collections import defaultdict
totals["positions_dict"] = defaultdict(list)
for position in totals["positions"]:
totals["positions_dict"][position.get_asset_type_display()].append(position)
Haven't tested this, because I don't have your data.
And I think it's rather ugly, but it just may work:
totals ['positions_dict'] = {
key: [
position
for position in totals ['positions']
if position.get_asset_type_display () == key
]
for key in {
position.get_asset_type_display ()
for position in totals ['positions']
}
}
But I would prefer something very simple, and avoid needless lookups / calls:
positions = totals ['positions']
positions_dict = {}
for position in positions:
key = position.get_asset_type_display ()
if key in positions_dict:
positions_dict [key] .append (position)
else:
positions_dict [key] = [position]
totals ['positions_dict'] = positions_dict
positions = totals ['positions']

operations with elements in list of list in python

This is my list:
volume = [['1.986', '3000'], ['1.987', '2000'], ['1.986', '700'],['1.987', '4000']]
How can I get the sum of volume[1] when volume[0] is the same price?
results = [['1.986', '3700'], ['1.987', '6000']]
Dictionaries would be a good data structure to use here. The default dict holds unique strings as the keys and assumes empty values are 0 because I set it to be based off of int.
from collections import defaultdict
d = defaultdict(int)
for v in volume:
d[v[0]] += int(v[1])
print d
If you need a list afterwards you can use a list comprehension:
list_version = [[key, value] for key,value in d]

How to find all specific dict objects with static value in dictionary

I have many dicts in my dictionary sturcture like
x = {'Shoes': 'http://www./', 'sub_categories': []}
It appears in some lists in dictionary
is there some possibility to remove all such objects like 'x' from my dictionary?
You can use a dict comprehension to iterate over the items, and check if the value is a list using isinstance.
>>> d = {'Shoes': 'http://www./', 'sub_categories': []}
>>> {k:v for k,v in d.items() if not isinstance(v, list)}
{'Shoes': 'http://www./'}

Refactoring with python dictionary comprehension

I have 2 dictionary which contain the same keys but the value pairs are different. Let's make dictA and dictB represent the two dictionaries in question.
dictA = {'key1':'Joe', 'key2':'Bob'}
dictB = {'key1':'Smith', 'key2':'Johnson'}
Currently, I am creating a new dictionary based the common occurring keys through a nested if statement. In doing so, the values that share a key are contained within a list, in the new dictionary. See this done below:
dictAB = {} # Create a new dictionary
# Create a list container for dictionary values
for key in dictA.keys():
dictAB[key] = []
# Iterate through keys in both dictionaries
# Find matching keys and append the respective values to the list container
for key, value in dictA.iteritems():
for key2, value2 in dictB.iteritems():
if key == key2:
dictAB[key].append(value)
dictAB[key].append(value2)
else:
pass
How can this be made into a more clean structure using python dictionary comprehension?
Use sets or key views (python 2.7):
dictAB = {k: [dictA[k], dictB[k]] for k in dictA.viewkeys() & dictB.viewkeys()}
Before 2.7:
dictAB = dict((k, [dictA[k], dictB[k]]) for k in set(dictA) & set(dictB))
In python 3, you can use the .keys method for such operations directly, as they are implemented as views:
dictAB = {k: [dictA[k], dictB[k]] for k in dictA.keys() & dictB.keys()}
Demo (python 2.7):
>>> dictA = {'key1':'Joe', 'key2':'Bob'}
>>> dictB = {'key1':'Smith', 'key2':'Johnson'}
>>> dictAB = {k: [dictA[k], dictB[k]] for k in dictA.viewkeys() & dictB.viewkeys()}
>>> print dictAB
{'key2': ['Bob', 'Johnson'], 'key1': ['Joe', 'Smith']}
The & operator on either two sets or on a dict view creates the intersection of both sets; all keys that are present in both sets.
By using an intersection of the keys, this code will work even if either dictA or dictB has keys that do not appear in the other dictionary. If you are absolutely sure the keys will always match, you could just iterate over either dict directly without the intersection:
dictAB = {k: [dictA[k], dictB[k]] for k in dictA}
dictAB = { key: [dictA[key],dictB[key]] for key in dictA if key in dictB }

Most efficient way to create a dictionary of empty lists in Python?

I am initializing a dictionary of empty lists. Is there a more efficient method of initializing the dictionary than the following?
dictLists = {}
dictLists['xcg'] = []
dictLists['bsd'] = []
dictLists['ghf'] = []
dictLists['cda'] = []
...
Is there a way I do not have to write dictLists each time, or is this unavoidable?
You can use collections.defaultdict it allows you to set a factory method that returns specific values on missing keys.
a = collections.defaultdict(list)
Edit:
Here are my keys
b = ['a', 'b','c','d','e']
Now here is me using the "predefined keys"
for key in b:
a[key].append(33)
If the keys are known in advance, you can do
dictLists = dict((key, []) for key in ["xcg", "bsd", ...])
Or, in Python >=2.7:
dictLists = {key: [] for key in ["xcg", "bsd", ...]}
If you adding static keys, why not just directly put them in the dict constructor?
dictLists = dict(xcg=[], bsd=[], ghf=[])
or, if your keys are not always also valid python identifiers:
dictLists = {'xcg': [], 'bsd': [], 'ghf': []}
If, on the other hand, your keys are not static or easily stored in a sequence, looping over the keys could be more efficient if there are a lot of them. The following example still types out the keys variable making this no more efficient than the above methods, but if keys were generated in some way this could be more efficient:
keys = ['xcg', 'bsd', 'ghf', …]
dictLists = {key: [] for key in keys}
You can also use a for loop for the keys to add:
for i in ("xcg", "bsd", "ghf", "cda"):
dictList[i] = []
In the versions of Python that support dictionary comprehensions (Python 2.7+):
dictLists = {listKey: list() for listKey in listKeys}

Categories

Resources