Related
I have two lists that have the same number of elements. In the first list, an element represents a category type. In the second list, an element represents a kind of cost. Indices corresponds to each other.
For example:
category_list = [1, 2, 2, 1, 3, 3, 3, 3, 4, 2]
cost_list = [30, 45, 21, 22, 21, 32, 11, 12, 13, 11]
On the condition that I pick one for every category, I would like to minimize the cost. How can I implement this? Faster, better. Thank you for your help.
I recommended this code. In here we use the prebuilt method 'zip' in python to iteratively get the category_list and cost_list so I supposed it is good practice and then I using conditional expression to create my logic. First I want to determine in that category already in my x_dict in that expression is true I using 'min' prebuilt method to compare the value that already exists and the new value of the related key. So it is helpful to manage our logic. Otherwise, that key does not already exist then we can added key-value pair for the first time. the dictionary key is must be unique that's why we using this logic.
category_list = [1, 2, 2, 1, 3, 3, 3, 3, 4, 2]
cost_list = [30, 45, 21, 22, 21, 32, 11, 12, 13, 11]
x_dict=dict()
for cat,cost in zip(category_list,cost_list):
if cat in x_dict:
x_dict[cat]=min(x_dict[cat],cost)
else:
x_dict[cat]=cost
print(x_dict)
Output
{1: 22, 2: 11, 3: 11, 4: 13}
We can use the zip method directly and convert it to the dictionary. It can filter the unique keys but the case is it given the last value for the related key which we use like given below.
x=dict(zip(category_list,cost_list))
print(x)
output
{1: 22, 2: 11, 3: 12, 4: 13}
You can see last cost of the given list assign to the related category. Thats we give that logic for our code.
You can store the minimum cost of each category in a dict.
category_list = [1, 2, 2, 1, 3, 3, 3, 3, 4, 2]
cost_list = [30, 45, 21, 22, 21, 32, 11, 12, 13, 11]
min_cst = dict()
for cat, cst in zip(category_list, cost_list):
if cat in min_cst:
min_cst[cat] = min(min_cst[cat], cst)
else:
min_cst[cat] = cst
print(min_cst)
# {1: 22, 2: 11, 3: 11, 4: 13}
The time complexity is O(N) and space complexity is O(N).
Since there are already three nearly-identical answers using dict, here is a different answer using min only once per category:
category_list = [1, 2, 2, 1, 3, 3, 3, 3, 4, 2]
cost_list = [30, 45, 21, 22, 21, 32, 11, 12, 13, 11]
pick_indices = [min((i for i in range(len(cost_list)) if category_list[i] == cat), key=lambda i: cost_list[i]) for cat in set(category_list)]
pick_totalcost = sum(cost_list[i] for i in pick_indices)
Or alternatively:
pick_costs = [min(cost for i,(cost,cat) in enumerate(zip(cost_list, category_list)) if cat == c) for c in set(category_list)]
pick_totalcost = sum(pick_costs)
Solution 1:
You can iterate over category_list and save a min of cost_list in a dictionary that key is category_list and you can use dictionary.get() and replace min with the minimum that exist before in the dictionary.
category_list = [1, 2, 2, 1, 3, 3, 3, 3, 4, 2]
cost_list = [30, 45, 21, 22, 21, 32, 11, 12, 13, 11]
dct_min = {}
for idx in range(len(category_list)):
min_item = dct_min.get(category_list[idx], cost_list[idx])
# alternative solution by thanks #Stef
# min_item = dct_min.setdefault(category_list[idx], cost_list[idx]); if cost_list[idx] < min_item: ...
if cost_list[idx] <= min_item:
dct_min[category_list[idx]] = cost_list[idx]
print(dct_min)
Output:
{1: 22, 2: 11, 3: 11, 4: 13}
Solution 2: (you can use zip then sort tuple first base index0 then index1 and convert sorted tuple to dictionary and we know in dictionary we have only one key.)
zip_lsts = list(zip(category_list, cost_list))
dict(sorted(zip_lsts, key=lambda element: (element[0], element[1]),reverse=True))
# {4: 13, 3: 11, 2: 11, 1: 22}
My code:
import random
randomlist = []
result_list=[]
l=int(input('Enter List Length'))
for i in range(0,l):
n = random.randint(1,30)
randomlist.append(n)
print(randomlist)
n=int(input('composite range:'))
composite_list = [randomlist[x:x + n] for x in range(0, len(randomlist), n)]
print(composite_list)
# zip inner list
for i in composite_list:
#stucked here
I wish to zip all list elements to a new list for example:
Random List: [25, 6, 15, 7, 21, 30, 10, 14, 3]
composite_list:[[25, 6, 15], [7, 21, 30], [10, 14, 3]]
Output list after zip: [[25, 7, 10],[6, 21, 14],[15, 30, 3]]
Because number of elements in composite_list is randomly. I have no idea how to use zip()
You can do the following:
rand_lst = [25, 6, 15, 7, 21, 30, 10, 14, 3]
it = iter(rand_lst)
comp_lst = list(zip(it, it, it))
# [(25, 6, 15), (7, 21, 30), (10, 14, 3)]
trans_lst = list(zip(*comp_lst))
# [(25, 7, 10), (6, 21, 14), (15, 30, 3)]
This uses the old "zip iterator with itself" pattern to create the chunks. Then you can zip the chunks by unpacking the list using the * operator. This also works in a single step:
it = iter(rand_lst)
trans_lst = list(zip(*zip(it, it, it)))
Use:
list(zip(*composite_list))
# output is a list of tuples
Or:
list(map(list, zip(*composite_list)))
# output is a list of lists
to look exactly your desired output.
Using numpy:
import numpy as np
np.array(composite_list).T.tolist()
Outputs:
[[25, 7, 10], [6, 21, 14], [15, 30, 3]]
Caveat would be probably even better, if you would keep your whole flow in numpy, otherwise converting to numpy might be a bit of a overhead.
I have a dictionary of values in tuple form, how to get the values in list form.
I want to get values from the tuples and create new lists and create another 3 lists with squares from them.
dictionary={1:(1,2,3),2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14)}
s=list(d.values())
d=[item for t in s for item in t]
print(d)
I used list comprehension i got this output:
[1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Using list comprehension
Expected_output:
[1,3,6,9,12],
[2,4,7,10,13],
[3,5,8,11,14],
squares**2 output above three list :
[1,9,36,81,144],
[4,16,49,100,169],
[9,25,64,121,196]
Provided with a Dictionary
First take a empty list and assign it to a variable “l”
Using list comprehension separate the values and store that in a variable
Iterate the values and append the empty list “l”
Now iterate the “l” using index values i[o], i[1], i[2] and store in various variables respectively
Using map function square the variables and store the values and print them using the list of variables
x = {
1:(1,2,3),
2:(4,5,6),
3:(7,8,9),
4:(10,11,12),
5:(13,14,15)
}
l = []
y = [i for i in x.values()]
for i in y:
l.append(i)
print(l)
m = [i[0] for i in l]
n = [i[1] for i in l]
o = [i[2] for i in l]
m1 = map(lambda i:i**2, m)
n1 = map(lambda i:i**2, n)
o1 = map(lambda i:i**2, o)
print(m)
print(list(m1))
print(n)
print(list(n1))
print(o)
print(list(o1))
you can use zip to collect the index elements of each list together, then use list comprehension to square them
dictionary={1:(1,2,3),2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14)}
list_vals = list(zip(*dictionary.values()))
squares = [[num ** 2 for num in nums] for nums in list_vals]
print(list_vals)
print(squares)
OUTPUT
[(1, 3, 6, 9, 12), (2, 4, 7, 10, 13), (3, 5, 8, 11, 14)]
[[1, 9, 36, 81, 144], [4, 16, 49, 100, 169], [9, 25, 64, 121, 196]]
Thanks to comments from #roganjosh highlighting that the dict will only be assured to be ordered if the pythong version is 3.6 or higher. If your python version is less than that you would first need to sort the values by order of the keys. Below is an example.
dictionary={2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14),1:(1,2,3)}
ordered_key_val = sorted(dictionary.items(), key=lambda items: items[0])
list_vals = list(zip(*[val for key, val in ordered_key_val]))
squares = [[num ** 2 for num in nums] for nums in list_vals]
print(list_vals)
print(squares)
You can use numpy to transpose the entire list once the values of the dictionary are obtained. You can use the below program
import numpy as np
dictionary={1:(1,2,3),2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14)}
list_out= []
for i in dictionary.keys():
list_out.append(dictionary[i])
tran_list = np.transpose(list_out)
out_list = tran_list*tran_list
Output of this is:
>>> out_list
array([[ 1, 9, 36, 81, 144],
[ 4, 16, 49, 100, 169],
[ 9, 25, 64, 121, 196]])
This is an array output! Anyway if you want it only in the list, ofcourse , you can play with it!
You can do this way:
>>> temp = list(zip(*dictionary.values()))
>>> [list(i) for i in temp]
[[1, 3, 6, 9, 12], [2, 4, 7, 10, 13], [3, 5, 8, 11, 14]]
>>> [[i**2 for i in elem] for elem in temp]
[[1, 9, 36, 81, 144], [4, 16, 49, 100, 169], [9, 25, 64, 121, 196]]
I have one dictionary here
d={1:(1,2,3),2:(4,5,6),3:(7,8,9),4:(10,11,12),5:(13,14,15)}
first I want to get values in tuple in three lists then I used list comprehension here The below code gives the tuple values in three lists
myList1 = [d [i][0] for i in (d.keys()) ]
print(myList1)
myList2 = [d [i][1] for i in (d.keys()) ]
print(myList2)
myList3 = [d [i][2] for i in (d.keys()) ]
print(myList3)
Here all the tuple values converted into list form
[1, 4, 7, 10, 13]
[2, 5, 8, 11, 14]
[3, 6, 9, 12, 15]
Now I want to squares the elements in three lists here I Used lambda expression the below code squares the elements in the lists
a1= list(map(lambda x: x**2 ,myList1))
print(a1)
a2= list(map(lambda x: x**2 ,myList2))
print(a2)
a3= list(map(lambda x: x**2 ,myList3))
print(a3)
The output is:
[1, 16, 49, 100, 169]
[4, 25, 64, 121, 196]
[9, 36, 81, 144, 225]
When declaring a list literal in Python, is it possible to merge an existing list into the declaration? For example:
l = [1, 2, 3]
n = [10, 20, 30, l, 50, 60, 70]
This results in the following:
[10, 20, 30, [1, 2, 3], 50, 60, 70]
Note that the list l itself has been added as a single element, but what I really want is for l's elements to be added individually to the target list, like this:
[10, 20, 30, 1, 2, 3, 50, 60, 70]
As of Python 3.5 (See https://www.python.org/downloads/release/python-350/, PEP448), This can be done using Python's unpack operator, which is an asterisk before the list:
l = [1, 2, 3]
n = [10, 20, 30, *l, 50, 60, 70]
The result is:
[10, 20, 30, 1, 2, 3, 50, 60, 70]
This will works with l on any place
from itertools import chain
for i in n:
if isinstance(i, list):
b+=list(chain(i))
else:
b+=[i]
I have
x = {2:[40,30],3:[24,16],4:[30,2],5:[0,80],6:[19,8]}
and I need to sort dictionary based on the 1st item in the value
so my result should be
{2:[40,30],4:[30,2],3:[24,16],6:[19,8],5:[0,80]}
All you need to do is using dict
d = dict(x)
Since your list is already in the right format to be easily converted to Dictionary, that is, you already have a key-value tuple pair as your list elements.
Simply pass it into dict():
>>> dict([(2, [40, 30]), (4, [30, 2])])
{2: [40, 30], 4: [30, 2]}
Dictionaries don't care what order their values are in:
>>> {'one': 1, 'two': 2} == {'two': 2, 'one': 1}
True
If you want to maintain order, you can use collections.OrderedDict:
>>> from collections import OrderedDict
>>> OrderedDict([(2, [40, 30]), (4, [30, 2])])
OrderedDict([(2, [40, 30]), (4, [30, 2])])
You weren't explicit in your question, but from your comments on other answers you want to preserve the order of the list in dictionary form. A standard dictionary is inherently unordered, however, you can use an OrderedDict instead:
from collections import OrderedDict
x = [(4, [30, 2]), (2, [40, 30])]
d = dict(x)
print(d)
# {2: [40, 30], 4: [30, 2]}
d = OrderedDict(x)
print(d)
# OrderedDict([(4, [30, 2]), (2, [40, 30])])
This preserves the keys in order of addition to the dictionary.