I'm trying to create a dictionary from a list in python. I'm creating alist from a .txt fril in the same directory as the .py file. But I don't understand how I create a dictionary without manually assigning a key to every value?
l = open ("Luther_King.txt").read()
words = l.split( )
print (words)
The print statement is just to check if it did in fact split the string into a list. Am I going to need to manually assign a key for every word or can I generate one somehow?
Unfortunately you have to have key and value. You can try this, send two list and merge them in a dictionary. You can just send a very basic list in order to have a key like : 1, 2, 3, 4, 5, ...
def get_dic_from_two_lists(keys, values):
return {keys[i]: values[i] for i in range(keys)}
I am going to take a wild guess- and suggest you use range of the size of your list to generate keys.Then zip them together,you'll have your dictionary!!
#Your original list
['Jack', 'Luther', 'Dima', 'Vijay']
#Generate another list,which will be your keys
key_list=range(1,5,1)
newdict = dict(zip(key_list, words))
#This is how new dict would look
{1: 'Jack', 2: 'Luther', 3: 'Dima', 4: 'Vijay'}
Related
I have the following list of values: Numbers = [1,2,3,4].
Is it possible to create a dictionary with the same name as the values contained in the list?
Example: dictionary_1 = {}
dictionary_2 = {}
....
dictionary_Number.. {}
I would like to create these dictionaries automatically, without creating them manually, reading the numbers contained in the list
You may use the keyword exec in python. Here is an example of your solution,
List = [1, 2,3]
for ele in List:
dic = f"Dictionary_{ele}"
exec(dic+" = {}")
print(Dictionary_1, Dictionary_2, Dictionary_3, sep='\n')
you may use it according to you, but the disadvantage for it is that you will need to use exec every time you need to use it or you must know what would be the name outcome of the first use of exec ...
I hope I helped...
Use the inbuild functions and remember that a dictionary needs a tuble (key & value):
Python Dictionaries
Python Dictionary fromkeys() Method
Example-Code:
Numbers = [1,2,3,4]
Numbers_dict = dict.fromkeys(Numbers,"dict_value")
print(Numbers_dict)
This will output:
{'1': 'dict_value', '2': 'dict_value', '3': 'dict_value', '4': 'dict_value'}
If you want to get a single dictonaries for each list-value, you first have to create for each list-value an empty variable.
After this you have to fill this empty vairables within a loop.
So I have a dictionary
dict={'Andrew':5, 'Brian':3, 'Clive':2, 'David':4}
it contains the names of volunteers and the number of times that they have volunteered for a particular duty. The dictionary is regularly updated by providing both the dictionary and a list to a function upd.
For the current update the following list has been declared - each name represents a new volunteer session:
ulist = ['Brian', 'David', 'Peter']
Write and demonstrate the function upd. Any ideas where to start
I have
def upd(lst):
I know its not much, but I am just learning about lists and dictionaries.
TIA
David.
EDIT:
My apologies, I should have been more specific
the upd function should create the dictionary and append/increment when a user is found, if not, it should create new user
Here is what I imagine your requirements are:
If a name in ulist is already in the dictionary, increment the value associated with it, otherwise create an entry for the name and initialize the value to 1.
This code is quite simple really. Just iterate through each name in ulist and check to see if it is in my_dictionary, if not then add it, if so then increment it.
my_dictionary = {'Andrew':5, 'Brian':3, 'Clive':2, 'David':4}
ulist = ['Brian', 'David', 'Peter']
def udp(lst):
for name in lst:
if name in my_dictionary:
my_dictionary[name] += 1
else:
my_dictionary[name] = 1
udp(ulist)
print(my_dictionary)
Results:
{'Andrew': 5, 'Brian': 4, 'Clive': 2, 'David': 5, 'Peter': 1}
Note: You named your dictionary dict which is technically a keyword in Python so I recommend changing it to something like my_dictionary as shown in my example.
I have three CSV files, one has a list of all pieces, one has a list of pieces of type M and the other one of type B. That means the first list contains the two other ones but without specifying their type.
I want to add a row to the frist list that specifies the type of pieces using python, that means for each piece in the first list, check if it's in list M and add an M in its type column, otherwise add a B.
My idea was to create a list of dictionaries (that I can convert later to CSV using a pre-written Python library), it would look something like this:
l = [{'piece','type'}] # list of dictionaries
for c in allpieces: # this is the list of all pieces:
l[{'piece'}] = c['piece'] # adding the piece number to the list of dictionaries from the list of all pieces
for m in mlist: # list of pieces of type m
if c['piece'] == m['piece']: # check of piece is found in listm
l[{'type'}] = 'm' # Add an m in its column
else: l[{'type'}] = 'b' # otherwise add b
This code is obviously not doing anything, and I need help debugging it.
A dictionary maps a key to a value like so {"key": "value} whereas elements in a list are accessed by providing the index so for first element in a list you do list[0] to get it. Now if you want to add new keys with values to a dictionary you can do it by adding them like such d["key"] = value. If you want to add to your list you do list.append(value). So in your case what you want to do is create a list with dictionaries inside I assume ? So that could look like that:
allpieces = ["Queen", "Tower", "Rook"]
mlist = ["Pawn", "Queen", "Rook"]
l = []
for c in allpieces:
if c in mlist:
l.append({"piece": c, "type": "m"})
else:
l.append({"piece": c, "type": "b"})
print(l)
Which creates a list with our dictionaries inside as such:
[{'piece': 'Queen', 'type': 'm'}, {'piece': 'Tower', 'type': 'b'}, {'piece': 'Rook', 'type': 'm'}]
Now if you were to access elements within this list you would do l[0]["piece"] to get "Queen"
I have a dictionary currently setup as
{'name': 'firm', 'name':'firm', etc},
Where keys are analyst names and values are analyst firms.
I am trying to create a new dictionary where the new values are the old k,v pairs and the associated key is simply the index (1, 2, 3, 4, etc).
Current code is below:
num_analysts = len(analysts.keys())
for k,v in analysts.items():
analysts_dict = dict.fromkeys(range(num_analysts), [k,v])
Current result
Each numeric key is getting given the same value (old k,v pair). What is wrong with my expression?
You can enumerate the items and convert them to a dictionary. However, dictionaries, in general, are not ordered. This means that the keys may be assigned essentially randomly.
dict(enumerate(analysts.items(), 1))
#{1: ('name1', 'firm1'), 2: ('name2', 'firm2')}
Enumerate and dictionary comprehension for this
d = {'name1': 'firm1', 'name2': 'firm2'}
d2 = {idx: '{}, {}'.format(item, d[item]) for idx, item in enumerate(d, start = 1)}
{1: 'name1, firm1', 2: 'name2, firm2'}
There are already effective answer posted by others. So I may just put the reason why your own solution does't work properly. It may caused by lazy binding. There are good resource on: http://quickinsights.io/python/python-closures-and-late-binding/
Because late binding will literally pick up the last one in dictionary you created. But this last one is not "virtually last one", it is determined by the OS. (Other people already give some explanation on dict data-structure.)
For each time you run in python command line the result may change. If you put the code in .py file, For each time you run in IDE, the result will be same.(always the last one in dict)
During each iteration, analysts_dict is assigned value based on the result of dict.items().
However, you should use comprehension to generate the final result in one line,
E.g. [{i: e} for i, e in enumerate(analysts.items())]
analysts = {
"a": 13,
"b": 123,
"c": 1234
}
num_analysts = len(analysts.keys())
analysts_dict = [{i: e} for i, e in enumerate(analysts.items())]
print(analysts_dict)
>> [{0: ('a', 13)}, {1: ('b', 123)}, {2: ('c', 1234)}]
This code
for k,v in analysts.items():
analysts_dict = dict.fromkeys(range(num_analysts), [k,v])
loops over the original dict and on each loop iteration it creates a new dict using the range numbers as the keys. By the way, every item in that dict shares a reference to a single [k, v] list object. That's generally a bad idea. You should only use an immutable object (eg None, a number, or a string) as the value arg to the dict.fromkeys method. The purpose of the method is to allow you to create a dict with a simple default value for the keys you supply, you can't use it to make a dict with lists as the values if you want those lists to be separate lists.
The new dict object is bound to the name analysts_dict. On the next loop iteration, a new dict is created and bound to that name, replacing the one just created on the previous loop, and the replaced dict is destroyed.
So you end up with an analysts_dict containing a bunch of references to the final [k, v] pair read from the original dict.
To get your desired result, you should use DYZ's code, which I won't repeat here. Note that it stores the old name & firm info in tuples, which is better than using lists for this application.
I have a dict like this:
(100002: 'APPLE', 100004: 'BANANA', 100005: 'CARROT')
I am trying to make my dict have ints for the keys (as it does now) but have sets for the values (rather than strings as it is now.) My goal is to be able to read from a .csv file with one column for the key (an int which is the item id number) and then columns for things like size, shape, and color. I want to add this information into my dict so that only the information for keys already in dict are added.
My goal dict might look like this:
(100002: set(['APPLE','MEDIUM','ROUND','RED']), 100004: set(['Banana','MEDIUM','LONG','YELLOW']), 100005: set(['CARROT','MEDIUM','LONG','ORANGE'])
Starting with my dict of just key + string for item name, I tried code like this to read the extra information in from a .csv file:
infile = open('FileWithTheData.csv', 'r')
for line in infile.readlines():
spl_line = line.split(',')
if int(spl_line[0]) in MyDict.keys():
MyDict[int(spl_line[0])].update(spl_line[1:])
Unfortunately this errors out saying AttributeError: 'str' object has no attribute 'update'. My attempts to change my dictionary's values into sets so that I can then .update them have yielded things like this: (100002: set(['A','P','L','E']), 100004: set(['B','A','N']), 100005: set(['C','A','R','O','T']))
I want to convert the values to a set so that the string that is currently the value will be the first string in the set rather than breaking up the string into letters and making a set of those letters.
I also tried making the values a set when I create the dict by zipping two lists together but it didn't seem to make any difference. Something like this
MyDict = dict(zip(listofkeys, set(listofnames)))
still makes the whole listofnames list into a set but it doesn't achieve my goal of making each value in MyDict into a set with the corresponding string from listofnames as the first string in the set.
How can I make the values in MyDict into a set so that I can add additional strings to that set without turning the string that is currently the value in the dict into a set of individual letters?
EDIT:
I currently make MyDict by using one function to generate a list of item ids (which are the keys) and another function which looks up those item ids to generate a list of corresponding item names (using a two column .csv file as the data source) and then I zip them together.
ANSWER:
Using the suggestions here I came up with this solution. I found that the section that has set()).update can easily be changed to list()).append to yield a list rather than a set (so that the order is preserved.) I also found it easier to update by .csv data input files by adding the column containing names to the FileWithTheData.csv so that I didn't have to mess with making the dict, converting the values to sets, and then adding in more data. My code for this section now looks like this:
MyDict = {}
infile = open('FileWithTheData.csv', 'r')
for line in infile.readlines():
spl_line = line.split(',')
if int(spl_line[0]) in itemidlist: #note that this is the list I was formerly zipping together with a corresponding list of names to make my dict
MyDict.setdefault(int(spl_line[0]), list()).append(spl_line[1:])
print MyDict
Your error is because originally your MyDict variable maps an integer to a string. When you are trying to update it you are treating the value like a set, when it is a string.
You can use a defaultdict for this:
combined_dict = defaultdict(set)
# first add all the values from MyDict
for key, value in MyDict.iteritems():
combined_dict[int(key)].add(value)
# then add the values from the file
infile = open('FileWithTheData.csv', 'r')
for line in infile.readlines():
spl_line = line.split(',')
combined_dict[int(sp_line[0])].update(spl_line[1:])
Your issue is with how you are initializing MyDict, try changing it to the following:
MyDict = dict(zip(listofkeys, [set([name]) for name in listofnames]))
Here is a quick example of the difference:
>>> listofkeys = [100002, 100004, 100005]
>>> listofnames = ['APPLE', 'BANANA', 'CARROT']
>>> dict(zip(listofkeys, set(listofnames)))
{100002: 'CARROT', 100004: 'APPLE', 100005: 'BANANA'}
>>> dict(zip(listofkeys, [set([name]) for name in listofnames]))
{100002: set(['APPLE']), 100004: set(['BANANA']), 100005: set(['CARROT'])}
set(listofnames) is just going to turn your list into a set, and the only effect that might have is to reorder the values as seen above. You actually want to take each string value in your list, and convert it to a one-element set, which is what the list comprehension does.
After you make this change, your current code should work fine, although you can just do the contains check directly on the dictionary instead of explicitly checking the keys (key in MyDict is the same as key in MyDict.keys()).