For my current Twitter Clone project that I am learning Python/Django through, I currently have a set of objects, Tweets, which I would like to sort by pub_date, which is of course the datetime of when they were published. Since sets don't have a sort method (or the convenient order_by that QuerySets have), what would be the best way to sort this set?
Thank you
You can produce a list of the sorted elements from the set via the standard sorted function, with a custom key functor to access the correct element to sort by. But you cannot sort the actual elements in a set, because set in python is by definition unordered.
The heading for the set documentation is literally 'Unordered collections of unique elements'. It's the same reason that set doesn't support access by index, because the order of the set changes with every element insertion.
You'll want to convert that set into a list. with your_list = list(your_set)
#To sort the list in place... by "pub_date"
your_list.sort(key=lambda x: x.pub_date, reverse=True)
#To return a new list, use the sorted() built-in function...
newlist = sorted(your_list, key=lambda x: x.pub_date, reverse=True)
You can pass your set to the sorted function which will return a sorted list, the sorted function will take a key, you can provide it with a customized function for sorting your items:
>>> s = set('abcde')
>>> s
set(['a', 'c', 'b', 'e', 'd'])
>>> sorted(s, key = lambda x: -ord(x))
['e', 'd', 'c', 'b', 'a']
Related
I have a dictionary
params = ImmutableMultiDict([('dataStore', 'tardis'), ('symbol', '1'), ('symbol', '2')])
I want to be able to iterate through the dictionary and get a list of all the values and their keys. However, when I try to do it, it only gets the first symbol key value pair and ignores the other one.
for k in params:
print(params.get(k))
If I understand you correctly you want to iterate over all keys, including duplicates, right? Then you could use the items(multi=False) method with multi set to True.
Documentation:
items(multi=False)
Return an iterator of (key, value) pairs.
Parameters: multi – If set to True the iterator returned will have a pair for each value of each key. Otherwise it will only contain
pairs for the first value of each key.
If I misunderstood you and you want a list of all entries to a single key have a look at jonrsharpe's answer.
If you read the docs for MultiDict, from which ImmutableMultiDict is derived, you can see:
It behaves like a normal dict thus all dict functions will only return the first value when multiple values for one key are found.
However, the API includes an additional method, .getlist, for this purpose. There's an example of its use in the docs, too:
>>> d = MultiDict([('a', 'b'), ('a', 'c')])
# ...
>>> d.getlist('a')
['b', 'c']
Code:
d = {'a': 0, 'b': 1, 'c': 2}
l = d.keys()
print l
This prints ['a', 'c', 'b']. I'm unsure of how the method keys() determines the order of the keywords within l. However, I'd like to be able to retrive the keywords in the "proper" order. The proper order of course would create the list ['a', 'b', 'c'].
Python 3.7+
In Python 3.7.0 the insertion-order preservation nature of dict objects has been declared to be an official part of the Python language spec. Therefore, you can depend on it.
Python 3.6 (CPython)
As of Python 3.6, for the CPython implementation of Python, dictionaries maintain insertion order by default. This is considered an implementation detail though; you should still use collections.OrderedDict if you want insertion ordering that's guaranteed across other implementations of Python.
Python >=2.7 and <3.6
Use the collections.OrderedDict class when you need a dict that
remembers the order of items inserted.
You could use OrderedDict (requires Python 2.7) or higher.
Also, note that OrderedDict({'a': 1, 'b':2, 'c':3}) won't work since the dict you create with {...} has already forgotten the order of the elements. Instead, you want to use OrderedDict([('a', 1), ('b', 2), ('c', 3)]).
As mentioned in the documentation, for versions lower than Python 2.7, you can use this recipe.
>>> print sorted(d.keys())
['a', 'b', 'c']
Use the sorted function, which sorts the iterable passed in.
The .keys() method returns the keys in an arbitrary order.
From http://docs.python.org/tutorial/datastructures.html:
"The keys() method of a dictionary object returns a list of all the keys used in the dictionary, in arbitrary order (if you want it sorted, just apply the sorted() function to it)."
Just sort the list when you want to use it.
l = sorted(d.keys())
Although the order does not matter as the dictionary is hashmap. It depends on the order how it is pushed in:
s = 'abbc'
a = 'cbab'
def load_dict(s):
dict_tmp = {}
for ch in s:
if ch in dict_tmp.keys():
dict_tmp[ch]+=1
else:
dict_tmp[ch] = 1
return dict_tmp
dict_a = load_dict(a)
dict_s = load_dict(s)
print('for string %s, the keys are %s'%(s, dict_s.keys()))
print('for string %s, the keys are %s'%(a, dict_a.keys()))
output:
for string abbc, the keys are dict_keys(['a', 'b', 'c'])
for string cbab, the keys are dict_keys(['c', 'b', 'a'])
I am trying to get ['a','b'] from the following variables in Python:
mylist = [{'A': ['a','b']}, {'B': ['c','d']}]
and
keys = ['A']
I have seen various questions with answers using itemgetter but this would only work when the keys of the dictionaries within the list are the same. (If I use itemgetter on my data, it will return me a KeyError)
Does anyone know how I could make this work?
Thanks!
I'd turn mylist into a single dictionary:
In [27]: d = dict(reduce(operator.add, (x.items() for x in mylist)))
and then query it like so:
In [28]: [d[k] for k in keys]
Out[28]: [['a', 'b']]
If I understood correctly, you want this:
mylist[0][keys[0]]
This is because your dictionary is placed in a list, so you need to get it out first like so: mylist[0]. You can then index the dictionary with the string 'A', which is also be the first element of a list, i.e. keys[0]. Putting the two together, you arrive at the highlighted statement above.
order = ['w','x','a','z']
[(object,'a'),(object,'x'),(object,'z'),(object,'a'),(object,'w')]
How do I sort the above list of tuples by the second element according the the key list provided by 'order'?
UPDATE on 11/18/13:
I found a much better approach to a variation of this question where the keys are certain to be unique, detailed in this question: Python: using a dict to speed sorting of a list of tuples.
My above question doesn't quite apply because the give list of tuples has two tuples with the key value of 'a'.
You can use sorted, and give as the key a function that returns the index of the second value of each tuple in the order list.
>>> sorted(mylist,key=lambda x: order.index(x[1]))
[('object', 'w'), ('object', 'x'), ('object', 'a'), ('object', 'a'), ('object', 'z')]
Beware, this fails whenever a value from the tuples is not present within the order list.
Edit:
In order to be a little more secure, you could use :
sorted(mylist,key=lambda x: x[1] in order and order.index(x[1]) or len(order)+1)
This will put all entries with a key that is missing from order list at the end of the resulting list.
Code:
d = {'a': 0, 'b': 1, 'c': 2}
l = d.keys()
print l
This prints ['a', 'c', 'b']. I'm unsure of how the method keys() determines the order of the keywords within l. However, I'd like to be able to retrive the keywords in the "proper" order. The proper order of course would create the list ['a', 'b', 'c'].
Python 3.7+
In Python 3.7.0 the insertion-order preservation nature of dict objects has been declared to be an official part of the Python language spec. Therefore, you can depend on it.
Python 3.6 (CPython)
As of Python 3.6, for the CPython implementation of Python, dictionaries maintain insertion order by default. This is considered an implementation detail though; you should still use collections.OrderedDict if you want insertion ordering that's guaranteed across other implementations of Python.
Python >=2.7 and <3.6
Use the collections.OrderedDict class when you need a dict that
remembers the order of items inserted.
You could use OrderedDict (requires Python 2.7) or higher.
Also, note that OrderedDict({'a': 1, 'b':2, 'c':3}) won't work since the dict you create with {...} has already forgotten the order of the elements. Instead, you want to use OrderedDict([('a', 1), ('b', 2), ('c', 3)]).
As mentioned in the documentation, for versions lower than Python 2.7, you can use this recipe.
>>> print sorted(d.keys())
['a', 'b', 'c']
Use the sorted function, which sorts the iterable passed in.
The .keys() method returns the keys in an arbitrary order.
From http://docs.python.org/tutorial/datastructures.html:
"The keys() method of a dictionary object returns a list of all the keys used in the dictionary, in arbitrary order (if you want it sorted, just apply the sorted() function to it)."
Just sort the list when you want to use it.
l = sorted(d.keys())
Although the order does not matter as the dictionary is hashmap. It depends on the order how it is pushed in:
s = 'abbc'
a = 'cbab'
def load_dict(s):
dict_tmp = {}
for ch in s:
if ch in dict_tmp.keys():
dict_tmp[ch]+=1
else:
dict_tmp[ch] = 1
return dict_tmp
dict_a = load_dict(a)
dict_s = load_dict(s)
print('for string %s, the keys are %s'%(s, dict_s.keys()))
print('for string %s, the keys are %s'%(a, dict_a.keys()))
output:
for string abbc, the keys are dict_keys(['a', 'b', 'c'])
for string cbab, the keys are dict_keys(['c', 'b', 'a'])