Dictionary initialization syntax - python

def __init__(self, devices, queue):
'''
'''
self.devices = devices
self.queue = queue
values = {k:0 for k in devices.keys()}
values[0xbeef] = len(values) # the number of devices
super(CallbackDataBlock, self).__init__(values)
Can someone help me explain the following two lines:
values = {k:0 for k in devices.keys()}
What does k:0 do?
values[0xbeef] = len(values) # the number of devices
Does this mean that new item {0xbeef: length} is appended in the dict?

The k is the field in the dictionary. The set of all fields is stored in the device.keys() which is most probably a list, we loop through the list, take names of fields and initialize them by zero.
Yes, you are right. The next statement is responsible for adding a new field and initializing it to the length of the array.

{k:0 for k in devices.keys()} creates a dictionary with all keys and 0 for all values. And your assessment is correct, it creates a new key with {value of 0xbeef : number of keys in the dictionary}

in python documentation you can see List Comprehensions
this pattern is important :
expression for item in list if conditional else
or for simple usage :
expression for item in list
in list data type we can use :
list = [0,1,2,3,4,5]
a = [x for x in list]
print (a)
printed :
[1,2,3,4,5]
and we have :
a = [x*2 for x in list]
print (a)
printed :
[2,4,6,8,10]
and for dictionary
in dictionary we have this syntax:
{key1:value1, key2:value2, . . .}
and example :
list = [0,1,2,3,4,5]
d = [k:0 for k in list]
print (d)
in example k:0 maens : put 0 for value of each k
printed :
{1: 0, 2: 0, 3: 0, 4: 0, 5: 0}
one more thing :
python dictionary have to Helpful method:dict.keys(),dict.values()
when we use dict.keys, python return a list of dict's keys
d = {"name":"sam", "job":"programer", "salary":"25000"}
print(d.keys())
print(d.values())
printed :
['name','job','salary']
['sam','programer','25000']
for add a new object in a dictionary we use :
d[newkey]= newValue
for example :
d[10] = 'mary'
print(d[10])
printed :
'mary'
now your answer :
in your code
1) k:0 maens : put 0 for value of each k
2) 0xbeef is a hex code == 48879 in decimal
values[48879] = len(values)
its fill by length of list.

Related

Converting two lists into a dictionary using built in list function?

I have been trying this for weeks! I tried this for weeks and all i get is nothing!
I searched internet and also the great STACK OVERFLOW but I couldn't find the one i need for!
Well normally if we try to change lists into dictionary we would get space between key and value!
for example:
Output:
The result dict is : {'Stack': '10'}
Well, I want the output as follows:
The result dict is : {'Stack':'10'}
Well the zip function would give a space between them and cause me an error!
And this is the result I have to get:
Enter list elements separated by ,(Comma) for list1: Stack,Over,Flow
Enter list elements separated by ,(Comma) for list2: 111,222,333
{'Stack':'111','Over':'222','Flow':'333'}
and for the code I tried is:
List_1 = input('Enter list elements separated by ,(Comma): ').split(',')
List_2 = input('Enter list elements separated by ,(Comma): ').split(',')
if len(List_1) == len(List_2) and len(List_1) != 0 and len(List_2) != 0 :
dict = dict(zip(List_1, List_2))
print(dict)
else:
print('The two lists are of different lengths. Try again.')
Since you want to be quite specific about the output I would do something like this:
def condensed_dict(data):
output = []
for item in data.items():
output.append('%r:%r' % item)
return '{%s}' % ''.join(output)
List_1 = input('Enter list elements separated by ,(Comma): ').split(',')
List_2 = input('Enter list elements separated by ,(Comma): ').split(',')
if List_1 and len(List_1) == len(List_2):
dict = dict(zip(List_1, List_2))
print(condensed_dict(dict))
else:
print('The two lists are of different lengths. Try again.')
PS: I simplified your if statement a bit.
Build your own string from the zipped lists directly, rather than using a dict.
>>> "{%s}" % ",".join(f"'{k}':'{v}'" for k, v in zip(List_1, List_2))
"{'Stack':'111','Over':'222','Flow':'333'}"
If you already have the dict, then build the string from the output of its items method.
>>> d = dict(zip(List_1, List2))
>>> "{%s}" % ",".join(f"'{k}':'{v}'" for k, v in d.items())
"{'Stack':'111','Over':'222','Flow':'333'}"
test_keys = ["Rash", "Kil", "Varsha"]
test_values = [1, 4, 5]
print ("Original key list is : " + str(test_keys))
print ("Original value list is : " + str(test_values))
# using zip()
# to convert lists to dictionary
res = dict(zip(test_keys, test_values))
print ("Resultant dictionary is : " + str(res))

Problem with retrieving the value of item in list/dictionary of objects in Python3

I'm trying to put string variables into list/dictionary in python3.7 and trying to retrieve them later for use.
I know that I can create a dictionary like:
string_dict1 = {"A":"A", "B":"B", "C":"C", "D":"D", "E":"E", "F":"F"}
and then retrieve the values, but it is not I want in this specific case.
Here is the code:
A = ""
B = "ABD"
C = ""
D = "sddd"
E = ""
F = "dsas"
string_dict = {A:"A", B:"B", C:"C", D:"D", E:"E", F:"F"}
string_list = [A,B,C,D,E,F]
for key,val in string_dict.items():
if key == "":
print(val)
for item in string_list:
if item == "":
print(string_list.index(item))
The result I got is:
E
0
0
0
And the result I want is:
A
C
E
0
2
4
If you print string_dict you notice the problem:
string_dict = {A:"A", B:"B", C:"C", D:"D", E:"E", F:"F"}
print(string_dict)
# output: {'': 'E', 'ABD': 'B', 'sddd': 'D', 'dsas': 'F'}
It contains a single entry with the value "".
This is because you are associating multiple values ​​to the same key, and this is not possible in python, so only the last assignment is valid (in this case E:"E").
If you want to associate multiple values ​​with the same key, you could associate a list:
string_dict = {A:["A","C","E"], B:"B", D:"D", F:"F"}
Regarding the list of strings string_list, you get 0 since the method .index(item) returns the index of the first occurrence of item in the list. In your case 0. For example, if you change the list [A,B,C,D,E,F] to [B,B,C,D,E,F]. Your code will print 2.
If you want to print the index of the empty string in your list:
for index, value in enumerate(string_list):
if value == '':
print(index)
Or in a more elegant way you can use a list comprehension:
[i for i,x in enumerate(string_list) if x=='']
Well, I don't think there's a way to get what you want from a dictionary because of how they work. You can print your dictionary and see that it looks like this:
{'': 'E', 'ABD': 'B', 'sddd': 'D', 'dsas': 'F'}
What happened here is A was overwritten by C and then E.
But I played around with the list and here's how I got the last three digits right:
for item in string_list:
if item != '':
print(string_list.index(item) - 1)
This prints:
0
2
4

is there a way to avoid nested loop

I'm given two different data and I'm wondering if there is a way to get specific data without using nested loop
firstdata = [[["key"],["value"]],
[[2],["two"]],
[[3],["three"]]]
seconddata = [[[key],["artimatic"]],
[[2],["0+2"]],
[[2],["1+1"]],
[[3],["0+3"]],
[[3],["1+2"]],
[[3],["2+1"]]]
//nested loop solution would look like this
for x in firstdata:
for y in seconddata:
print(x[1])
if x[0]==y[0]:
print(y)
Is there an alternative solution that I can loop the seconddata without using nested loop?
**Ok I am assuming Data Structure of firstdata and seconddata will be same:
firstdata_dict = {x[0][0]: x[1][0] for x in firstdata}
seconddata_dict = {}
for data in seconddata:
if not seconddata_dict.has_key(data[0][0]):
seconddata_dict[data[0][0]] = []
seconddata_dict[data[0][0]].append(data[1][0])
for key, value in firstdata_dict.items():
if seconddata_dict.get(key):
# key match add your algo
print seconddata_dict[key]
Output:
['0+2', '1+1']
['0+3', '1+2', '2+1']
['artimatic']
Start by converting the list to a dictionary as so. Here the keys are the numbers 2 and 3, and values are list of strings associated to a specific key in the list
def convert_to_dct(lst):
dct = {}
for x in lst:
for i in range(len(x)):
key = x[0][0]
value = x[1][0]
if key in dct:
dct[key].append(value)
else:
dct[key] = []
return dct
This function converts the list as follows
firstdata = [[["key"],["value"]],
[[2],["two"]],
[[3],["three"]]]
seconddata = [[["key"],["artimatic"]],
[[2],["0+2"]],
[[2],["1+1"]],
[[3],["0+3"]],
[[3],["1+2"]],
[[3],["2+1"]]]
firstdict = convert_to_dct(firstdata)
seconddict = convert_to_dct(seconddata)
print(firstdict)
print(seconddict)
#{'key': ['value'], 2: ['two'], 3: ['three']}
#{'key': ['artimatic'], 2: ['0+2', '1+1', '1+1'], 3: ['0+3', '1+2', '1+2', '2+1', '2+1']}
Then to get your final result, do
for key in firstdict.keys():
if key in seconddict.keys():
print(seconddict[key])
#['artimatic']
#['0+2', '1+1', '1+1']
#['0+3', '1+2', '1+2', '2+1', '2+1']
I don't think the two answers understand the question correctly, so here you go:
Create your data
firstData = [[["key"],["value"]],
[[2],["two"]],
[[3],["three"]]]
secondData = [[['key'],["artimatic"]],
[[2],["0+2"]],
[[2],["1+1"]],
[[3],["0+3"]],
[[3],["1+2"]],
[[3],["2+1"]]]
Then
firstdata_dict = {x[0][0]: x[1][0] for x in firstData} #Creates the dictionary of first Data
Then do the computation
for element in secondData:
if (element[0][0] in firstdata_dict): #Checks in a hashMap and is thus done in O(1) generally
print(element)

Python get keys from ordered dict

python noob here. So I'm making a program that will take a JSON file from a url and parse the information and put it into a database. I have the JSON working, thankfully, but now I am stuck, I'll explain it through my code.
playerDict = {
"zenyatta" : 0,
"mei" : 0,
"tracer" : 0,
"soldier76" : 0,
"ana" : 0,
...}
So this is my original dictionary with the which I then fill with the players data for each hero.
topHeroes = sorted(playerDict.items(),key = operator.itemgetter(1),reverse = True)
I then sort this list and it turns the heroes with the most amount of hours played first.
topHeroesDict = topHeroes[0:3]
playerDict['tophero'] = topHeroesDict[0]
I then get the top three heroes. The second line here prints out a list like so:
'secondhero': ('mercy', 6.0)
Whereas I want the output to be:
'secondhero': 'mercy'
Would appreciate any help i have tried the code below with and without list.
list(topHeroes.keys())[0]
So thanks in advance and apologies for the amount of code!
You could take an approach with enumerate, if instead of "firsthero" you are ok with "Top 1" and so on. With enumerate you can iterate over the list and keep track of the current index, which is used to name the key in this dictionary comprehension. j[0] is the name of the hero, which is the first element of the tuple.
topHeroes = sorted(playerDict.items(),key = operator.itemgetter(1),reverse = True)
topHeroesDict = {"Top "+str(i): j[0] for i, j in enumerate(topHeroes[0:3])}
Alternatively, you could use a dictionary which maps the index to first like this:
topHeroes = sorted(playerDict.items(),key = operator.itemgetter(1),reverse = True)
top = {0: "first", 1: "second", 2: "third"}
topHeroesDict = {top[i]+"hero": j[0] for i, j in enumerate(topHeroes[0:3])}
You do not need any imports to achieve this. Without itemgetter, you can do it in one line like this:
top = {0: "first", 1: "second", 2: "third"}
topHeroesDict = {top[i]+"hero": j[0] for i, j in enumerate(sorted([(i, playerDict[i]) for i in playerDict.keys()], key = lambda x: x[1], reverse = True)[0:3])}
You're sorting an iterable of tuples returned by the items method of the dict, so each item in the sorted list is a tuple containing the hero and their score.
You can avoid using sorted and dict.items altogether and get the leading heroes (without their score) by simply using collections.Counter and then getting the most_common 3 heroes.
from collections import Counter
player_dict = Counter(playerDict)
leading_heroes = [hero for hero, _ in player_dict.most_common(3)]

Loop through entries in a list and create new list

I have a list of strings that looks like that
name=['Jack','Sam','Terry','Sam','Henry',.......]
I want to create a newlist with the logic shown below. I want to go to every entry in name and assign it a number if the entry is seen for the first time. If it is being repeated(as in the case with 'Sam') I want to assign it the corresponding number, include it in my newlist and continue.
newlist = []
name[1] = 'Jack'
Jack = 1
newlist = ['Jack']
name[2] = 'Sam'
Sam = 2
newlist = ['Jack','Sam']
name[3] = 'Terry'
Terry = 3
newlist = ['Jack','Sam','Terry']
name[4] = 'Sam'
Sam = 2
newlist = ['Jack','Sam','Terry','Sam']
name[5] = 'Henry'
Henry = 5
newlist = ['Jack','Sam','Terry','Sam','Henry']
I know this can be done with something like
u,index = np.unique(name,return_inverse=True)
but for me it is important to loop through the individual entries of the list name and keep the logic above. Can someone help me with this?
Try using a dict and checking if keys are already paired to a value:
name = ['Jack','Sam','Terry','Sam','Henry']
vals = {}
i = 0
for entry in name:
if entry not in vals:
vals[entry] = i + 1
i += 1
print vals
Result:
{'Henry': 5, 'Jack': 1, 'Sam': 2, 'Terry': 3}
Elements can be accessed by "index" (read: key) just like you would do for a list, except the "index" is whatever the key is; in this case, the keys are names.
>>> vals['Henry']
5
EDIT: If order is important, you can enter the items into the dict using the number as the key: in this way, you will know which owner is which based on their number:
name = ['Jack','Sam','Terry','Sam','Henry']
vals = {}
i = 0
for entry in name:
#Check if entry is a repeat
if entry not in name[0:i]:
vals[i + 1] = entry
i += 1
print (vals)
print (vals[5])
This code uses the order in which they appear as the key. To make sure we don't overwrite or create duplicates, it checks if the current name has appeared before in the list (anywhere from 0 up to i, the current index in the name list).
In this way, it is still in the "sorted order" which you want. Instead of accessing items by the name of the owner you simply index by their number. This will give you the order you desire from your example.
Result:
>>> vals
{1: 'Jack', 2: 'Sam', 3: 'Terry', 5: 'Henry'}
>>> vals[5]
'Henry'
If you really want to create variable.By using globals() I am creating global variable .If you want you can create local variable using locals()
Usage of globals()/locals() create a dictionary which is the look up table of the variable and their values by adding key and value you are creating a variable
lists1 = ['Jack','Sam','Terry','Sam','Henry']
var = globals()
for i,n in enumerate(nl,1):
if n not in var:
var[n] = [i]
print var
{'Jack':1,'Sam': 2,'Terry': 3, 'Henry':5}
print Jack
1
If order of the original list is key, may I suggest two data structures, a dictionary and a newlist
d = {}
newlist = []
for i,n in enumerate(nl):
if n not in d:
d[n] = [i+1]
newlist.append({n: d[n]})
newlist will return
[{'Jack': [1]}, {'Sam': [2]}, {'Terry': [3]}, {'Sam': [2]}, {'Henry': [5]}]
to walk it:
for names in newlist:
for k, v in names.iteritems():
print('{} is number {}'.format(k, v))
NOTE: This does not make it easy to lookup the number based on the name as other suggested above. That would require more data structure logic. This does however let you keep the original list order, but keep track of the time the name was first found essentially.
Edit: Since order is important to you. Use orderedDict() from the collections module.
Use a dictionary. Iterate over your list with a for loop and then check to see if you have the name in the dictionary with a if statement. enumerate gives you the index number of your name, but keep in mind that index number start from 0 so in accordance to your question we append 1 to the index number giving it the illusion that we begin indexing from 1
import collections
nl = ['Jack','Sam','Terry','Sam','Henry']
d = collections.OrderedDict()
for i,n in enumerate(nl):
if n not in d:
d[n] = [i+1]
print d
Output:
OrderedDict([('Jack', [1]), ('Sam', [2]), ('Terry', [3]), ('Henry', [5])])
EDIT:
The ordered dict is still a dictionary. So you can use .items() to get the key value pairs as tuples. the number is essectially a list so you can do this:
for i in d.items():
print '{} = {}'.format(i[0],i[1][0]) #where `i[1]` gives you the number at that position in the tuple, then the `[0]` gives you the first element of the list.
Output:
Jack = 1
Sam = 2
Terry = 3
Henry = 5

Categories

Resources