I have a dictionary where the keys are integers and the values are strings. The dictionary has been sorted using key values.
I need to copy the corresponding string values (keeping the sorted order) to a list. I cannot figure out how to iterate over the dictionary.
I know the number of key-value pairs in the dictionary (let it be 'n').
Some_ordered_dict
resultant_list=[]
for i in range(n):
resultant_list.append(Some_ordered_dict[increment-key?]
The dictionary was sorted using OrderedDict from some dictionary 'dic' as follows;
od=collections.OrderedDict(sorted(dic.items()))
The essential point is that I have to display the strings values of the dictionary in the same order as they appear in the sorted dictionary.
resultant_list = [d[k] for k in sorted(d)]
The standard Python dictionary does not guarantee that items in a dictionary will be kept in any order. Next thing is that you have to iterate using a "for in" statement like such:
Some_ordered_dict
resultant_list=[]
for i in Some_ordered_dict:
resultant_list.append(Some_ordered_dict[i])
You should take a look at the ordered dict collection to ensure that the items on your dict are kept in the order that you expect.
Using the standard unordered dictionary in python you could use something like this:
resultant_list = []
for i in sorted(dict.keys()):
resultant_list.append(dict[i])
As mentioned in other posts, dictionaries do not guarantee order. One way to get a sorted list would be to created a list of tuples out of your dict's (key, value) pairs, then sort this list based n the first element(the key), as follows:
my_dict = {2: 'two', 3: 'three', 1: 'one'}
my_tuple_list = list(zip(my_dict.keys(), my_dict.values()))
my_sorted_list = sorted(my_tuple_list, key = lambda item: item[0])
resultant_list = [x[1] for x in my_sorted_list]
Related
So I have a list of tuples of the form:
my_list=[('a','aa','aaa',0),('a','aa','aab',1),('a','ab','aba',2)]
And I need it to convert it to a nested dictionary:
out={'a':{'aa':{'aaa':0,'aab':1},'ab':{'aba':2}}}
The crucial piece of my setting is that I do not know in advance the length of the tuples in my_list (4 is just an example). Is there an easy way to generalize the cases I saw in other answers (e.g. Python list of tuples to nested dict or Convert a list of variable length Tuples into Dictionary) beyond the fixed 3-element tuples they use?
I made various attempts with recursive functions but I do not have anything close to a solution.
Just loop over the first keys, setting aside the last pair of items which will be a key-value pair, and set dictionaries in-between (using setdefault here, but you could do that part manually):
result = {}
for *keys, last_key, value in my_list:
current = result
for key in keys:
current = current.setdefault(key, {})
current[last_key] = value
Just to be explicit by what I mean by "manually" (I guess I should rather say "explicitly"):
result = {}
for *keys, last_key, value in my_list:
current = result
for key in keys:
if key not in current:
current[key] = {}
current = current[key]
current[last_key] = value
I have a list of frozensets that I'd like to sort, Each of the frozensets contains a single integer value that results from an intersection operation between two sets:
k = frozenset(w) & frozenset(string.digits)
d[k] = w # w is the value
list(d) # sorted(d) doesn't work since the keys are sets and sets are unordered.
Here is the printed list:
[frozenset({'2'}), frozenset({'1'}), frozenset({'4'}), frozenset({'3'})]
How can I sort the list using the values contained in the sets?
You need to provide function as key to sorted which would accept frozenset as argument and return something which might be compared. If each frozenset has exactly 1 element and said element is always single digit then you might use max function (it will extract that single element, as sole element is always biggest element of frozenset) that is
d1 = [frozenset({'2'}), frozenset({'1'}), frozenset({'4'}), frozenset({'3'})]
d2 = sorted(d1,key=max)
print(d2)
output
[frozenset({'1'}), frozenset({'2'}), frozenset({'3'}), frozenset({'4'})]
If you want to know more read Sorting HOW TO
Previous answers can not sorted correctly, Because of strings
d = [frozenset({'224'}), frozenset({'346'}), frozenset({'2'}), frozenset({'22345'})]
sorted(d, key=lambda x: int(list(x)[0]))
Output:
[frozenset({'2'}),
frozenset({'224'}),
frozenset({'346'}),
frozenset({'22345'})]
Honestly, unless you really need to keep the elements as frozenset, the best might be to generate a list of values upstream ([2, 1, 4, 3]).
Anyway, to be able to sort the frozensets you need to make them ordered elements, for instance by converting to tuple. You can do this transparently using the key parameter of sorted
l = [frozenset({'2'}), frozenset({'1'}), frozenset({'4'}), frozenset({'3'})]
sorted(l, key=tuple)
or natsorted for strings with multiple digits:
from natsort import natsorted
l = [frozenset({'2'}), frozenset({'1'}), frozenset({'14'}), frozenset({'3'})]
natsorted(l, key=tuple)
output:
[frozenset({'1'}), frozenset({'2'}), frozenset({'3'}), frozenset({'14'})]
I have this list:
source = ['sourceid', 'SubSourcePontiflex', 'acq_source', 'OptInSource', 'source',
'SourceID', 'Sub-Source', 'SubSource', 'LeadSource_295', 'Source',
'SourceCode', 'source_code', 'SourceSubID']
I am iterating over XML in python to create a dictionary for each child node. The dictionary varies in length and keys with each iteration. Sometimes the dictionary will contain a key that is also an item in this list. Sometimes it wont. What I want to be able to do is, if a key in the dictionary is also an item in this list then append the value to a new list. If none of the keys in the dictionary are in list source, I'd like to append a default value. I'm really having a brain block on how to do this. Any help would be appreciated.
Just use the in keyword to check for membership of some key in a dictionary.
The following example will print [3, 1] since 3 and 1 are keys in the dictionary and also elements of the list.
someList = [8, 9, 7, 3, 1]
someDict = {1:2, 2:3, 3:4, 4:5, 5:6}
intersection = [i for i in someList if i in someDict]
print(intersection)
You can just check if this intersection list is empty at every iteration. If the list is empty then you know that no items in the list are keys in the dictionary.
in_source_and_dict = set(mydict.keys()).intersection(set(source))
in_dict_not_source = set(mydict.keys()) - set(source)
in_source_not_dict = set(source) - set(mydict.keys())
Iterate over the result of which one you want. In this case I guess you'll want to iterate over in_source_not_dict to provide default values.
In Python 3, you can perform set operations directly on the object returned by dict.keys():
in_source_and_dict = mydict.keys() & source
in_dict_not_source = mydict.keys() - source
in_source_not_dict = source - mydict.keys()
This will also work in Python 2.7 if you replace .keys() by .viewkeys().
my_dict = { some values }
values = []
for s in sources:
if my_dict.get(s):
values += [s]
if not values:
values += [default]
You can loop through the sources array and see if there is a value for that source in the dictionary. If there is, append it to values. After that loop, if values is empty, append the default vaule.
Note, if you have a key, value pair in your dictionary (val, None) then you will not append the None value to the end of the list. If that is an issue you will probably not want to use this solution.
You can do this with the any() function
dict = {...}
keys = [...]
if not any(key in dict for key in keys):
# no keys here
Equivalently, with all() (DeMorgan's laws):
if all(key not in dict for key in keys):
# no keys here
I have a dictionary of objects where the key is a simple string, and the value is a data object with a few attributes. I'd like to sort my dictionary based on an attribute in the values of the dictionary. i have used this to sort based on the dictionaries values
sorted = dict.values()
sorted.sort(key = operator.attrgetter('total'), reverse=True)
This yields a sorted list of values (which is expected) and I lose my original keys from the dictionary (naturally). I would like to sort both the keys and values together... how can I achieve this? Any help would be greatly appreciated?
Use .items() (or its iterator version iteritems) instead of .values() to get a list of (key, value) tuples.
items = sorted(dct.iteritems(), key=lambda x: x[1].total, reverse=True)
You'll want to use .items() rather than .values(), for example:
def keyFromItem(func):
return lambda item: func(*item)
sorted(
dict.items(),
key=keyFromItem( lambda k,v: (v['total'], k) )
)
The above will sort first based on total, and for items with equal total, will sort them alphabetically by key. It will return items as (key,value) pairs, which you could just do [x[1] for x in sorted(...)] to get the values.
Use items instead of values - and a just use a lambda to fecth the sorting key itself, since there won't be a ready made operator for it:
sorted = dict.items()
sorted.sort(key = lambda item: item[1].total, reverse=True)
I wrote the below code working with dictionary and list:
d = computeRanks() # dictionary of id : interestRank pairs
lst = list(d) # tuples (id, interestRank)
interestingIds = []
for i in range(20): # choice randomly 20 highly ranked ids
choice = randomWeightedChoice(d.values()) # returns random index from list
interestingIds.append(lst[choice][0])
There seems to be possible error because I'm not sure if there is a correspondence between indices in lst and d.values().
Do you know how to write this better?
One of the policies of dict is that the results of dict.keys() and dict.values() will correspond so long as the contents of the dictionary are not modified.
As #Ignacio says, the index choice does correspond to the intended element of lst, so your code's logic is correct. But your code should be much simpler: d already contains IDs for the elements, so rewrite randomWeightedChoice to take a dictionary and return an ID.
Perhaps it will help you to know that you can iterate over a dictionary's key-value pairs with d.items():
for k, v in d.items():
etc.