max value of a list filled with named tuples - python

I create a list filled with named tuples:
from collections import namedtuple
Point = namedtuple('Point', 'x y')
a = Point(5,4)
b = Point(8,3)
tab = [a,b]
print tab
>>[Point(x=5, y=4), Point(x=8, y=3)]
I would like to have the max of the x values in the list 'tab'
max(tab.x)
>> 8

Try like this,
>>> max(tab, key=lambda k: k.x)
Point(x=8, y=3)
>>> max(tab, key=lambda k: k.x).x
8
The optional key argument specifies a one-argument ordering function
like that used for list.sort(). The key argument, if supplied, must be
in keyword form (for example, max(a,b,c,key=func)).
https://docs.python.org/2/library/functions.html#max

You may simple do it as :
print max([i.x for i in tab])
However it may not be the best approach to do the same.

Related

Adding things to the emptiest list? (python)

I am looking for a simple way to compare the content of multiple lists and find the one with the fewest variables.
Then I want to set the new variable to be added to that list.
Example:
list1 = [1,5,7,12,4,8]
list2 = [3,2,9,11,14,6,10]
list3 = [13,15,16]
In this I would want it to find list3 to be the shortest and append the new value to it.
Due to pythons min, max, and sort's key keyword argument this is fairly simple to do in python
min([list1, list2, list3..], key = len).append(item)
key corresponds to the function applied to each element and whose result is used for comparison in both min and max. in this case the function len (which retrieves the length of sequence objects like list and tuple and any class that defines __len__ ) is used.
from min.
The key argument specifies a one-argument ordering function like that used for list.sort()
from list.sort()
key specifies a function of one argument that is used to extract a comparison key from each list element (for example, key=str.lower).
example
>>> x = [11231]
>>> y = [1,2,3,4,5]
>>> z = [1,2,3,4,1,1]
>>> min([x,y,z], key = len)
[11231]
You could write a small function that checks the len of each list, then append to that list.
def add_to_shortest(lists, item):
min(lists, key = lambda i: len(i)).append(item)
For example
>>> add_to_shortest([list1, list2, list3], 5)
>>> list3
[13, 15, 16, 5]

Dictionary of pair in python

I am new to python and was trying to make a dict of pairs in python.
What I would have done in c++ is
dist[make_pair(a,b)]=1
I am not sure how I can do the same in python
Edit
What I basically want to do is to map a pair of two integers to some value-
for example-
(1,2) -> 1
(1,3) -> 2
(2,1) ->3
I want to map pairs to some integer value
You can use the data structure "tuple" as a key in the dictionary. If you want to define a function that returns a n-tuple given n inputs, you can do that also.
a = 4
b = 5
dict_example = dict()
dict_example[(a,b)] = 1
print dict_example[(a,b)]
This prints the value of key (a,b), which is 1
To create an element having the tuple (a,b) as key, and 1 as a value, you just have to do :
new_dict = {(a,b) : 1}
If such a dict already exist, and you want to add the pair a,b as a key and 1 as a value, you have to do :
existing_dict[(a,b)] = 1
You can also use existing_dict[a,b] = 1 as Duncan pointed out.
I guess you tried using an array as a dict key, like:
>>> d = {}
>>> pair = [0, 1]
>>> d[pair] = 'foo'
TypeError: unhashable type: 'list'
Ok, what is that? Python dict keys must not be mutable. They can be numbers, strings and other hashable types - you can't use mutable types like lists, dicts and other mutable collections.
There is a collection that is very like a list but is not mutable: the tuple.
>>> d[tuple(pair)] = 'foo'
>>> d
{(1, 2): 'foo'}
As you can see, the literal for a tuple is (v1, v2, ..., vN). In places where it is not ambiguous, you can even omit the parenthesis:
>>> pair = 0, 1
>>> pair
(0, 1)
More than once I was bit by this when I left a trailing comma while refactoring code:
>>> x = 1, # I meant x = 1
>>> x
(1,)
That is the literal for a tuple with just 1 element.

how collections.defaultdict.get work in max statement's key paramter--- python

I have read these post 1, 2, 3, but I still can not figure out following python code:
>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
... d[k] += 1
...
>>> lis = ['m', 'i', 's', 'p']
>>> max(lis, key=d.get)
'i'
I know the times that a letter occurs stored in d. And when I input:
>>> d.get
<built-in method get of collections.defaultdict object at 0x7f506ed8d710>
It said that get is a method. Why it dose not use parenthesis? And what kind of data form it returns?
max accepts a keyword argument -- a "key" function. e.g.:
max(iterable, key=some_function)
Which (I'm guessing) is how you're using it (instead of max(iterable, function))
The "key" function will be called for every element in the iterable and the result of the "key" function is used to compare elements.
So, in your case, the element for which d.get returns the maximal value will be returned.
d is your defaultdict. d.get(key) returns the value associated with that key -- and the things which are getting passed to it are keys that are in d. So you're picking out the key which has the maximal value.

(python) How do I obtain specific entries from a dictionary (using keys) as I do with an array?

With an array x=['A','B','C'], I can obtain several elements from it by just stating the index: eg.print(x[0:2]) yields ['A','B'].
Now for a similar (ordered) dictionary x={1:'A', 2:'B', 3:'C'}, how would I obtain 'A' and 'B' in the same way, by referencing the keys 1 and 2? Trying a method similar to the array above gives me an error:
TypeError: unhashable type: 'slice'
Note that the key tied to the entries are important, so it won't help converting the dictionary into a list.
Also, I plan on doing this to a lot of entries (>100), so calling each individual one won't be useful. My real program will involve numbered keys starting from 100 and calling keys 200 to 300, for example.
The way to retrieve a value from a dictionary is dict_name[key]:
print x[1], x[2]
>> 'A', 'B'
Note that if the key doesn't exist this will raise a KeyError.
A way around it is to use get(key, default_value):
print x[9]
>> KeyError
print x.get(9, None)
>> None
You can use a for loop in order to check multiple keys:
for potential_key in range(10):
print x[potential_key]
You can use operator.itemgetter:
>>> from operator import itemgetter
>>> x = {1:'A', 2:'B', 3:'C'}
>>> itemgetter(1, 2)(x)
('A', 'B')
>>> get_1_2 = itemgetter(1, 2) # Alternative: Save the result function
>>> get_1_2(x) # call it later
('A', 'B')
You can map get() to the object that describes which keys you want, such as range() (which has syntax and results similar to that of slicing):
>>> x={1:'A', 2:'B', 3:'C'}
>>> print(*map(x.get, range(1,3)))
A B
Or a generator expression instead of map():
>>> x={1:'A', 2:'B', 3:'C'}
>>> print(*(x.get(item) for item in range(1,3)))
A B
>> list(x.values())[0:2]
This gives the output: ['A', 'B']
Since you mentioned 'ordered' dictionary, this could be a possible solution but without referencing the keys.

How to get the list with the higher sum of its elements

I was wondering if anyone could help me with a Python problem I have. I have four lists, each list holds floats (decimals). I'm adding all the floats that each list contains. The part I'm stuck on is I want to know which of the four list has a higher sum. I know I could use if statements but does anyone know a more of a efficient way. For instance:
foodmart = [12.33,5.55]
nike = [42.20,69.99]
gas_station = [0.89,45.22]
toy_store = [10.99,15.32]
use max():
>>> max(foodmart,nike,gas_station,toy_store, key=sum)
>>> [42.2, 69.99]
help() on max:
max(iterable[, key=func]) -> value
max(a, b, c, ...[, key=func]) ->
value
With a single iterable argument, return its largest item. With two or
more arguments, return the largest argument.
Represent the lists as a dict and use max with an optional key function to calculate the sum
Instead of representing the lists in the way you did, use a dictionary. It would be easier to determine the correct shop and work on any number of lists / shops without the need to enumerate them in the max routine. This would be more Pythonic and maintainable
>>> shops = dict()
>>> shops['foodmart'] = [12.33,5.55]
>>> shops['nike'] = [42.20,69.99]
>>> shops['gas_station'] = [0.89,45.22]
>>> shops['toy_store'] = [10.99,15.32]
>>> max(shops, key = lambda k:sum(shops[k]))
'nike'
>>> max([1,2],[3,4],[2,3], key=lambda x: sum(x))
[3, 4]

Categories