-1

So I've realised that I need to append things into an empty list. How do I do what I've commented, I've written it out in Pseudocode but I dont actually know how to fully code it.

def number_letter(a, b):
lst = []
##a is the letters ["A", "B", "C"]
##b is the lists of numbers [[0.5, 0.5, 0], [0.05, 0.3, 0.65]]
##together if a user was calling it, it would look like this
##number_letter(["A", "B", "C"], [[0.5, 0.5, 0], [0.05, 0.3, 0.65]])
##Outputs relating numbers from 'b' with letters from 'a' in descending order (the values are summed)
##[[0.8, "B"], [0.65, "C"], [0.55, "A"]]
Jack Jock
  • 15
  • 5

3 Answers3

1

Here it goes in one liner inside your "number_letter" function

sorted(dict(zip(a,map(sum, zip(b[0], b[1])))).items(), key=lambda x: x[1], reverse=True)

in details

#sum list column wise
list_sum = map(sum, zip(b[0], b[1]))
# create a dictionary with key and value list
dictionary = dict(zip(a,list_sum))
#sort it by value in descending order
sorted(dictionary, key=lambda x: x[1], reverse=True)
John
  • 1,212
  • 1
  • 16
  • 30
0

One liner

def number_letter(a, b):
    return [[*x]for x in sorted(zip(map(sum,zip(*b)),a),key=lambda x:x[0],reverse=True)]

EDIT: An IDLE session

>>> b
[[0.5, 0.5, 0], [0.05, 0.3, 0.65]]

>>> list(zip(b[0],b[1]))
[(0.5, 0.05), (0.5, 0.3), (0, 0.65)]  #zips elements from argument iterables together

>>> sum( (1,2) )  #the name says it all
3

>>> foo=lambda a,b: a+b  #lambdas are temporary functions generally passed in as argument to other functions
>>> foo(1, 2)
3

>>> list(map( int, ['1', '2'] ))  #maps each of the value(s) from the argument iterable(s) to the function (int in this case)
[1, 2]
>>> list(map(foo, [1,2], [4,5]))
[5, 7]

>>> print(b)
[[0.5, 0.5, 0], [0.05, 0.3, 0.65]]
>>> print(*b)
[0.5, 0.5, 0] [0.05, 0.3, 0.65]  # * unpacks the iterable's elements

>>> sorted([2, 4, 7, 1, 3],reverse=True)  #returns a new sorted list, passing keyword arg reverse as True sorts in descending order
[7, 4, 3, 2, 1]

>>> #Now for the best part: list comprehensions (or comprehensions in general)
>>> lst = [1,2,3,4]
>>> [ 3*x for x in lst]  #i'd suggest you read about it as i don't want to ruin learning for you, i'm sorry if i did already.
[3, 6, 9, 12]

EDIT 2: Putting it all together.

>>> a
['A', 'B', 'C']
>>> b
[[0.5, 0.5, 0], [0.05, 0.3, 0.65]]

>>> x = list(map(sum,zip(*b))) #zip b[0] and b[1] and find the sum
>>> print(x)
[0.55, 0.8, 0.65]
>>> x2 = list(zip(x,a)) #[(0.55, 'A'), (0.8, 'B'), (0.65, 'C')]

>>> x3 = sorted(x2,key=lambda x:x[0],reverse=True) #sort x2 in desc order of first elements
>>> print(x3)
[(0.8, 'B'), (0.65, 'C'), (0.55, 'A')]

>>> #this is only for OP's requirement of the elements to be lists
>>> y = [ [*k] for k in x3]
>>> print(y)
[[0.8, 'B'], [0.65, 'C'], [0.55, 'A']]
frederick99
  • 1,033
  • 11
  • 18
  • Open for any suggestions. : ) – frederick99 Apr 27 '17 at 13:35
  • 1
    Sweet mother mary, it works but please explain how! I'm very new to python and dont know what a key is, or a map, or lambda ! – Jack Jock Apr 27 '17 at 13:40
  • python docs are a good place to start if you are not afraid of reading. – frederick99 Apr 27 '17 at 13:42
  • what does the '*' before x do in the for loop? @frederick99 – Jack Jock Apr 27 '17 at 13:54
  • Note that you don't need `zip(b[1], b[0])` because you're mapping `sum` to it. It won't matter what order the elements of the two `b` lists are placed in the `zip`, and in fact it can just be `map(sum, zip(*b))`. – ely Apr 27 '17 at 13:54
  • @ely nice! I'll add it. (: – frederick99 Apr 27 '17 at 13:57
  • @JackJock The `*` syntax "unpacks" arguments in Python, taking each element of some sequence and providing it as if it was the next positional argument in a function call. So `f(a, b, c)` can be written as `f(*[a, b, c])`. Here is [more discussion](http://stackoverflow.com/q/2921847/567620). The `**` unpacking operator is the same, except it must operate on something like a `dict` that has key-value pairs, and the key will be used as a name for a named argument in the unpacking. – ely Apr 27 '17 at 13:57
  • @frederick99, Stack Overflow is a place for learning. If you're going to provide an answer you should include an explanation of how it works / why it's better as a matter of course. I agree with Jack; you should [edit] your answer and explain what you've done. (I also think this one-liner is very difficult to read, and I'm an experienced Python developer. I would ask you to break it up into multiple statements in code review. Please consider that when you update it. This isn't code golf.) – ChrisGPT was on strike Apr 27 '17 at 14:01
0

This all hinges on an argsort implementation, and for Python you'll want to use numpy.argsort.

In [16]: def number_letter(a, b):
    ...:     sums = list(map(sum, zip(*b)))
    ...:     return [[sums[i], a[i]] for i in numpy.argsort(sums)[::-1]]
    ...: 

In [17]: number_letter(["A", "B", "C"], [[0.5, 0.5, 0], [0.05, 0.3, 0.65]])
Out[17]: [[0.8, 'B'], [0.65, 'C'], [0.55, 'A']]

For pure Python, you'll want to implement your own argsort function.

ely
  • 74,674
  • 34
  • 147
  • 228
  • thank you so much for the advice and answer, I'm extremely new to python, do you mind explaining with an argsort function is? – Jack Jock Apr 27 '17 at 13:42
  • 1
    Furthermore is there a longer but perhaps simpler way to do it? – Jack Jock Apr 27 '17 at 13:43
  • It's simple to implement in Python, just the syntax can be a little tricky. Here are [some examples](http://stackoverflow.com/a/6979121/567620), which is what ties this answer to the other 'one-liner' answer. Argosrt in general is an algorithm that provides you with the new index positions that would result after sorting. So in your case, sorting by the sums means index 0 goes to index 2 (0.55 goes to last), index 1 goes to index 0 (0.8 goes to first), and index 2 goes to index 1 (0.65 goes to middle). So the argsort of the weightings will be `[1, 2, 0]`. – ely Apr 27 '17 at 13:50
  • Since `numpy.argsort` assumes the data are sorted ascending, I have to add the `[::-1]` syntax to the end of it, which is Python slice syntax for reversing elements of an iterable sequence, effectively treating it as a descending sort. – ely Apr 27 '17 at 13:51