I am reading items from a txt file into a list and then converting it into a dictionary as follows-
def getfeatures_into_list(inputfilename):
fid=open(inputfilename,"r")
dict_Lab_Features=defaultdict(int)
list1=[]
for line in fid:
list1.append(line.rstrip().lower())
list1=list(set(list1)) #Removing duplicates
c=0
for items in sorted(list1):
dict_Lab_Features[items]=c
c+=1
dict_Lab_Features=sorted(dict_Lab_Features.items(), key=operator.itemgetter(1))
print(dict_Lab_Features['Hello'])
I am getting error in the print statement
list indices must be integer,not str
Edit I want to sort the dict by value in ascending order.
In this line:
dict_Lab_Features=sorted(dict_Lab_Features.items(), key=operator.itemgetter(1))
you have reassigned dict_Lab_Features so that it is a list. This is because the output of sorted() is always a list. Naturally, a list cannot take a string as an index.
You should learn to think of dictionaries as inherently unsorted. There is such a thing as an OrderedDict for when you really need to keep track of insertion order, but for most purposes, a regular dict is fine. You just have to get into the habit of traversing the dictionary in the desired order, not worrying about whether the dictionary is stored in any kind of order.
The usual way to traverse a dictionary in sorted order is to just loop over the sorted keys, such as:
for key in sorted(dict_Lab_Features):
print dict_Lab_Features[key]
or
for key, value in sorted(dict_Lab_Features.items()):
print value
Or, if you want to loop over the sorted values,
for value in sorted(dict_Lab_Features.values()):
print value
You cannot sort a dict. Dicts are unordered mappings of elements.
Let's analyize the following line:
dict_Lab_Features=sorted(dict_Lab_Features.items(), key=operator.itemgetter(1))
From the documentation of sorted:
Return a new sorted list from the items in iterable.
So after that, dict_Lab_Features is a sorted list of key-value tuples. After that you try to index it with 'Hello'
print(dict_Lab_Features['Hello'])
Here you try to index that list with 'Hello', that's why you get the error list indices must be integer,not str
dict_Lab_Features stops being a dict when you call dict.items(). A dict.items() object cannot be addressed using string keys (it's really just a list of tuples [(key, value), ... ]).
Furthermore, "sorting" a dictionary you then intend to use by name doesn't make much sense either. Looks like you either need a collections.OrderedDict or you should skip ordering altogether
Related
Given the following code
all_options = { "1": "/test/1", "2": "/test/2", "3": "/test/3" }
selected_options = [ "1", "3" ]
How do I get the entries from all_options where the key matches an entry in selected_options?
I started down the path of using a List Comprehension, but I'm stuck on the last clause:
final = ()
[ final.append(option) for option in all_options if ... ]
Thank you
Just like this?
>>> dict((option, all_options[option]) for option in selected_options if option in all_options)
{'1': '/test/1', '3': '/test/3'}
From Python 2.7 and 3 onwards, you can use the dict comprehension syntax:
{option : all_options[option] for option in selected_options if option in all_options}
Or if you just want the values:
>>> [all_options[option] for option in selected_options if option in all_options]
['/test/1', '/test/3']
[option for option in all_options if option in selected_options]
You may want to make a set of selected_options and use that instead if there are many.
How do I get the entries from all_options where the key matches an entry in selected_options?
With a comprehension. We have two kinds: list comprehensions and generator comprehensions.
Note that this depends on what you mean by "entries". If you want a dict with the key/value pairs that match, then you'll need a comprehension that creates the key/value pairs, and then use that to create a dict by feeding it to the dict constructor.
There is a special syntax rule that says that if we call something callable (like, say, a class constructor) with just one argument, and that argument is a generator comprehension, then we only need one pair of parentheses (instead of two: one to call the function and another to mark the comprehension as a comprehension). This lets us write very natural-looking things.
On the other hand, if you just want a list of keys, then you can just use a list comprehension. (You could pass a generator comprehension to the list constructor, too.)
I started down the path of using a List Comprehension...
You have the wrong idea, fundamentally, about how they work. You don't use them to perform an action repeatedly; you use them to calculate a result repeatedly. You wouldn't make an append call in the first part of the statement because (a) the comprehension is already building the sequence for you, so there's no reason to create another empty sequence to append to; (b) the append call returns None after doing the appending, so you end up with a list of None values that you subsequently throw away.
A list comprehension creates a value. A generator comprehension also creates a value, but it's a generator (so you have to extract its values to use them).
So, how do we write the code?
A list of keys looks like this: for each key in the dict (iterating over a dict iterates over its keys), we want that key (with no modification), only if the key is in our other list. That is, we want [key for key in all_options if key in selected_options]. And that's exactly how you write it in Python. A language could hardly read any more naturally while still being unambiguous.
A dict of key-value pairs looks like this: for each key-value pair in the key-value pairs of the dict, we want that pair, only if the key is in our other list. We want to make a dict using those key-value pairs, so we wrap the comprehension in the dict constructor. To get key-value pairs from a dict, we iterate over its .items(). So, we want a dict constructed from a key and value, for each key and value in the items of the original dict, where the key is in the other list. And again, that's exactly what we write: dict((key, value) for (key, value) in all_options if key in selected_options).
In more recent versions of Python, we can also use a "dict comprehension", which is basically syntactic sugar so that we can write something that looks more like the list comprehension.
Use set() instead, and take advantage of the intersection operation:
>>> final = set(all_options.keys()) & set(selected_options)
>>> print(final)
{'1', '3'}
The above only returns the keys, but NullUserException notes that the question may want the value as well, using a dict comprehention:
>>> {x: all_options[x] for x in set(all_options.keys()) & set(selected_options)}
{'1': '/test/1', '3': '/test/3'}
For completeness, here's just the value:
>>> [all_options[x] for x in set(all_options.keys()) & set(select_options)]
['/test/1', '/test/3']
The below is wrong. Using set() iterates over both lists, instead of just one.
Using sets is better assuming the options become large. The conditional list comprehensions check every item in one of the containers, but a set intersection takes advantage of Python's excellent hashing. Even the list comprehension here only looks up the desired keys in all_options.
I'm not sure which exact contents you're trying to return, so I'm giving a couple of choices:
if your trying to return: ['1', '3']
[option for option in all_options if option in selected_options]
OR
if you're trying to return: ['/test/1', '/test/3']
[all_options[option] for option in all_options if option in selected_options]
json_data = {"fruits": ["apple", "banana", "orange"],"vegetables":["tomatoe", "cucumber", "potato"]}
How do I access my array numerically without having to include a numeric key?
ex:
json_data[0][0] #result should equal "apple"
You can't. The outer container is an unordered dictionary, not a list, so an index of 0 is meaningless. If you have some way of ordering the keys, you could then use the dict.keys() function to build a list and index that. The problem is, that keys() can come up in any order, so you'd still need some other ordering principle.
json_data[list(json_data.keys())[0]][0]
this is how to do it, but it is extremely wrong, ugly and unpythonic, and you should probably be looking for another way to do this.
starting from the inside json_data.keys() returns all the keys
list() turns those keys into a list [0] after it, accesses the zeroth item in the list
json_data[] around that accesses the list by key
[0] after it accesses the zeroth item in the returned list
Also it is not guaranteed to work 100% of the time, because json_data.keys() is not guaranteed to always output at the same order.
I have a dictionary such as below.
d = {
'0:0:7': '19734',
'0:0:0': '4278',
'0:0:21': '19959',
'0:0:14': '9445',
'0:0:28': '14205',
'0:0:35': '3254'
}
Now I want to sort it by keys with time priority.
Dictionaries are not sorted, if you want to print it out or iterate through it in sorted order, you should convert it to a list first:
e.g.:
sorted_dict = sorted(d.items(), key=parseTime)
#or
for t in sorted(d, key=parseTime):
pass
def parseTime(s):
return tuple(int(x) for x in s.split(':'))
Note that this will mean you can not use the d['0:0:7'] syntax for sorted_dict though.
Passing a 'key' argument to sorted tells python how to compare the items in your list, standard string comparison will not work to sort by time.
Dictionaries in python have no guarantees on order. There is collections.OrderedDict, which retains insertion order, but if you want to work through the keys of a standard dictionary in order you can just do:
for k in sorted(d):
In your case, the problem is that your time strings won't sort correctly. You need to include the additional zeroes needed to make them do so, e.g. "00:00:07", or interpret them as actual time objects, which will sort correctly. This function may be useful:
def padded(s, c=":"):
return c.join("{0:02d}".format(int(i)) for i in s.split(c))
You can use this as a key for sorted if you really want to retain the current format in your output:
for k in sorted(d, key=padded):
Have a look at the collections.OrderedDict module
I have a dictionary d for which the keys are all strings. Now when I do:
for key in d:
print(d[key])
I get the elements of d is some "random" order. How can I force the element of d to come out sorted by the lexicographical order?
Sort before iterating.
for key in sorted(d):
Use sorted() to sort any iterable, including a dictionary:
for key in sorted(d):
print(d[key])
Additionaly to those answers, if your dictionary is immutable but have significant amount of items and need to be read more often than once, it might be useful to repack items using the collections.OrderedDict container.
Given the following code
all_options = { "1": "/test/1", "2": "/test/2", "3": "/test/3" }
selected_options = [ "1", "3" ]
How do I get the entries from all_options where the key matches an entry in selected_options?
I started down the path of using a List Comprehension, but I'm stuck on the last clause:
final = ()
[ final.append(option) for option in all_options if ... ]
Thank you
Just like this?
>>> dict((option, all_options[option]) for option in selected_options if option in all_options)
{'1': '/test/1', '3': '/test/3'}
From Python 2.7 and 3 onwards, you can use the dict comprehension syntax:
{option : all_options[option] for option in selected_options if option in all_options}
Or if you just want the values:
>>> [all_options[option] for option in selected_options if option in all_options]
['/test/1', '/test/3']
[option for option in all_options if option in selected_options]
You may want to make a set of selected_options and use that instead if there are many.
How do I get the entries from all_options where the key matches an entry in selected_options?
With a comprehension. We have two kinds: list comprehensions and generator comprehensions.
Note that this depends on what you mean by "entries". If you want a dict with the key/value pairs that match, then you'll need a comprehension that creates the key/value pairs, and then use that to create a dict by feeding it to the dict constructor.
There is a special syntax rule that says that if we call something callable (like, say, a class constructor) with just one argument, and that argument is a generator comprehension, then we only need one pair of parentheses (instead of two: one to call the function and another to mark the comprehension as a comprehension). This lets us write very natural-looking things.
On the other hand, if you just want a list of keys, then you can just use a list comprehension. (You could pass a generator comprehension to the list constructor, too.)
I started down the path of using a List Comprehension...
You have the wrong idea, fundamentally, about how they work. You don't use them to perform an action repeatedly; you use them to calculate a result repeatedly. You wouldn't make an append call in the first part of the statement because (a) the comprehension is already building the sequence for you, so there's no reason to create another empty sequence to append to; (b) the append call returns None after doing the appending, so you end up with a list of None values that you subsequently throw away.
A list comprehension creates a value. A generator comprehension also creates a value, but it's a generator (so you have to extract its values to use them).
So, how do we write the code?
A list of keys looks like this: for each key in the dict (iterating over a dict iterates over its keys), we want that key (with no modification), only if the key is in our other list. That is, we want [key for key in all_options if key in selected_options]. And that's exactly how you write it in Python. A language could hardly read any more naturally while still being unambiguous.
A dict of key-value pairs looks like this: for each key-value pair in the key-value pairs of the dict, we want that pair, only if the key is in our other list. We want to make a dict using those key-value pairs, so we wrap the comprehension in the dict constructor. To get key-value pairs from a dict, we iterate over its .items(). So, we want a dict constructed from a key and value, for each key and value in the items of the original dict, where the key is in the other list. And again, that's exactly what we write: dict((key, value) for (key, value) in all_options if key in selected_options).
In more recent versions of Python, we can also use a "dict comprehension", which is basically syntactic sugar so that we can write something that looks more like the list comprehension.
Use set() instead, and take advantage of the intersection operation:
>>> final = set(all_options.keys()) & set(selected_options)
>>> print(final)
{'1', '3'}
The above only returns the keys, but NullUserException notes that the question may want the value as well, using a dict comprehention:
>>> {x: all_options[x] for x in set(all_options.keys()) & set(selected_options)}
{'1': '/test/1', '3': '/test/3'}
For completeness, here's just the value:
>>> [all_options[x] for x in set(all_options.keys()) & set(select_options)]
['/test/1', '/test/3']
The below is wrong. Using set() iterates over both lists, instead of just one.
Using sets is better assuming the options become large. The conditional list comprehensions check every item in one of the containers, but a set intersection takes advantage of Python's excellent hashing. Even the list comprehension here only looks up the desired keys in all_options.
I'm not sure which exact contents you're trying to return, so I'm giving a couple of choices:
if your trying to return: ['1', '3']
[option for option in all_options if option in selected_options]
OR
if you're trying to return: ['/test/1', '/test/3']
[all_options[option] for option in all_options if option in selected_options]