Let's say I have a dictionary (MxN = 4x3 matrix) that has keys of integers and values of lists as follows:
d={1:[10,11,12], 2:[13,14,15], 3:[16,17,18], 4:[19,20,21]}
I am trying to get a list that looks like this:
new_list_1 = [10,13,16,19]
In this case, I am trying to get the first element of each value (list) in the dictionary and put it into a new list. However, I would also like to do this for other indexes as well such as:
new_list_2 = [11,14,17,20]
or
new_list_3 = [12,15,18,21]
Once I have these lists, ideally I would like to them in a new dictionary of dimension NxM :
d_new = {0:new_list_1, 1:new_list_2, 2:new_list_3}
Thanks!
You can use
new_list_1 = [v[0] for v in d.values()]
new_list_2 = [v[1] for v in d.values()]
new_list_3 = [v[2] for v in d.values()]
then use
d_new = {0:new_list_1, 1:new_list_2, 2:new_list_3}
Value of d_new :
{0: [10, 13, 16, 19], 1: [11, 14, 17, 20], 2: [12, 15, 18, 21]}
Alternatively:
d_new = {i:[v[i] for v in d.values()] for i in range(0,3)}
Would also do the same
convert your dict values to list of list (2d matrix) and then use transpose of that matrix and then make the result according to your needs.
res = {i: list(k) for i ,k in enumerate(list(zip(*d.values())))}
print(res)
# {0: [10, 13, 16, 19], 1: [11, 14, 17, 20], 2: [12, 15, 18, 21]}
With numpy you can:
import numpy as np
d = {
1: [10, 11, 12],
2: [13, 14, 15],
3: [16, 17, 18],
4: [19, 20, 21],
}
a = np.array(list(d.values()))
a = a.T
Output:
array([[10, 13, 16, 19],
[11, 14, 17, 20],
[12, 15, 18, 21]])
Back to dict:
d = {n+1: l for n, l in enumerate(a.tolist())}
Output:
{1: [10, 13, 16, 19], 2: [11, 14, 17, 20], 3: [12, 15, 18, 21]}
You can use pandas as well:
import pandas as pd
d_new = pd.DataFrame.from_dict(d, orient = 'index').to_dict('list')
Hope this helps!
You can do it simply like so:
d_new = {}
for i in range(len(list(d.values())[0])):
d_new[i] = [x[i] for x in d.values()]
Hope it helps :)
Easy to understand:
d={1:[10,11,12], 2:[13,14,15], 3:[16,17,18], 4:[19,20,21]}
d_new = {}
for i in range(len(d[1])):
l = []
for v in d.values():
l.append(v[i])
d_new[i] = l
print(d_new)
output:
{0: [10, 13, 16, 19], 1: [11, 14, 17, 20], 2: [12, 15, 18, 21]}
Code :
lista_1 = []
lista_2 = []
lista_3 = []
d_new = {}
for i in d.values():
for h, j in enumerate(i):
if h == 0:
lista_1.append(j)
d_new[h] = lista_1
elif h == 1:
lista_2.append(j)
d_new[h] = lista_2
else:
lista_3.append(j)
d_new[h] = lista_3
Output :
{0: [10, 13, 16, 19], 1: [11, 14, 17, 20], 2: [12, 15, 18, 21]}
Maybe this can help you, it is for beginners' understanding!
Related
Given two lists with the same length:
a = [15, 10, 15, 14]
b = [14, 15, 14, 14]
What is the minimal number of changes needed for 'a' to become 'b'?
This is my attempt at it:
c3=0
fht2= [15, 10, 15, 14]
sht2= [14, 15, 14, 14]
for i in range(0,len(fht2)):
for j in range(0,len(sht2)):
if fht2==sht2:
c=0
else:
if fht2!=sht2:
if fht2[i]!=sht2[j] and fht2[i]<=sht2[j]:
fht2[i]+=abs(fht2[i]-sht2[j])
c3+=1
if fht2[i]!=sht2[j] and fht2[i]>=sht2[j]:
fht2[i]-=abs(fht2[i]-sht2[j])
c3+=1
print(fht2)
print(c3)
The output should be:
[14, 15, 14, 14]
3
However, my output is :
[14, 14, 14, 14]
11
Please assist.
a = [15, 10, 15, 14]
b = [14, 15, 14, 14]
list_length = len(a)
print("list length:",list_length)
counter = 0
for i in range(list_length):
if a[i]!= b[i]:
counter = counter + 1
print ("minimal number of changes is:",counter)
Output:
list length:4
minimal number of changes is: 3
Please learn to write a better question
I am tasked with finding the exact coordinate of a maximum value in a list of lists in python. This list of lists is referred to as a grid to emulate topographical coordinates.
Here is the grid, along with my code to find the maximum:
grid = [[15, 16, 18, 19, 12, 11],
[13, 19, 23, 21, 16, 12],
[12, 15, 17, 19, 22, 10],
[10, 14, 16, 13, 9, 6]]
maxi = 0
for i in grid:
for j in i:
if j > maxi:
maxi = j
This code finds the maximum, however I am stuck on finding the coordinates. The output should be:
global max: (1,2) 23
Because the maximum (23) is on the First row, and on the second column.
I have tried using index and find but they do not work or take my value as an input. Any tips or help are appreciated, thank you in advance.
You can use the builtin function enumerate.
Update your code to this:
grid = [[15, 16, 18, 19, 12, 11],
[13, 19, 23, 21, 16, 12],
[12, 15, 17, 19, 22, 10],
[10, 14, 16, 13, 9, 6]]
maxi = -float('inf')
maxCoord = None
for i, row in enumerate(grid):
for j, col in enumerate(row):
if col > maxi:
maxi = col
maxCoord = (i, j)
print(maxCoord, maxi) #(1, 2) 23
Enumerate could be an option, as it was already proposed. If you want to keep your original function to find the max value, you can call its coordinates using:
for sublist in grid:
if maxi in sublist:
print(grid.index(sublist), sublist.index(maxi))
I hope y'all doing fine!
So I want to make 5 groups of 6 people randomly chosen from a list and then append those 6 chosen names to the special group.
Example: If a, b, c, d, e, f, are the first six chosen names -> append those names to group1;
after the group1 contains 6 names, then the next 6 names -> append to group2; and so and so till I have 5 groups of 6 people.
I hope you understand me and that you can help :)
My code:
import random
names = [30 names i dont wanna share]
group1 = list()
group2 = list()
group3 = list()
group4 = list()
group5 = list()
def choosegroup():
def chooserandom():
return(random.choice(names))
def creategroup():
for i in range(1,7):
chosed = chooserandom()
names.remove(chosed)
#while(chosed in group1):
#print('Ups')
#print(chosed + ' already chosed')
# chosed = chooserandom()
#print(chosed)
group1.append(chosed)
#print('Group 1:' + '\n' + str(group1) + '\n')
createdgroup = creategroup()
print(group1)
for i in range(1,6):
print(f'Group {i}')
choosegroup()
group1.clear()
random.shuffle(names)
groups = [ names[i:i+6] for i in range(0, len(names), 6) ]
Now groups[0], groups[1] etc. are your 6-person groups.
Once you have your list of names, to split them into random groups, I would instead use numpy
import numpy as np
groups = np.array(names)
np.shuffle(groups)
groups = np.reshape(groups, (5,6))
As an example with numbers instead of names
>>> names = np.arange(30)
>>> names
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
>>> np.random.shuffle(names)
>>> names
array([ 8, 18, 23, 7, 25, 14, 11, 20, 13, 24, 15, 26, 19, 21, 12, 17, 0,
6, 3, 10, 29, 9, 16, 28, 22, 5, 1, 4, 27, 2])
>>> np.reshape(names, (5,6))
array([[ 8, 18, 23, 7, 25, 14],
[11, 20, 13, 24, 15, 26],
[19, 21, 12, 17, 0, 6],
[ 3, 10, 29, 9, 16, 28],
[22, 5, 1, 4, 27, 2]])
You can access them from globals as such:
globals()[f"group{i}"]
though storing and retrieving them from a dictionary is preferable.
You can rewrite your code as follows:
import random
from collections import defaultdict
names = [30 names i dont wanna share]
groups = defaultdict(list)
def choosegroup(group_name):
def chooserandom():
return(random.choice(names))
def creategroup(group_name):
for i in range(1,7):
chosed = chooserandom()
names.remove(chosed)
groups[group_name].append(chosed)
createdgroup = creategroup()
print(group_name, "\n", group[group_name])
for i in range(1,6):
print(f'Group {i}')
group_name = f"group{i}"
choosegroup(group_name)
groups[group_name].clear()
I have a list of numbers as
N = [13, 14, 15, 25, 27, 31, 35, 36, 43]
After some calculations, for each element in N, I get the following list as the answers.
ndlist = [4, 30, 0, 42, 48, 4, 3, 42, 3]
That is, for the first index in N (which is 13), my answer is 4 in ndlist.
For some indices in N, I get the same answer in ndlist. For example, when N= 13 and 31, the answer is 4 in ndlist.
I need to find the numbers in N (13 and 31 in my example) such that they have the same answer in ndlist.
Can someone help me to that?
You can use a defaultdict and put those into a list keyed by the answer like:
Code:
N = [13, 14, 15, 25, 27, 31, 35, 36, 43]
ndlist = [4, 30, 0, 42, 48, 4, 3, 42, 3]
from collections import defaultdict
answers = defaultdict(list)
for n, answer in zip(N, ndlist):
answers[answer].append(n)
print(answers)
print([v for v in answers.values() if len(v) > 1])
Results:
defaultdict(<class 'list'>, {4: [13, 31], 30: [14],
0: [15], 42: [25, 36], 48: [27], 3: [35, 43]})
[[13, 31], [25, 36], [35, 43]]
Here is a way using only a nested list comprehension:
[N[idx] for idx, nd in enumerate(ndlist) if nd in [i for i in ndlist if ndlist.count(i)>1]]
#[13, 25, 31, 35, 36, 43]
To explain: the inner list comprehension ([i for i in ndlist if ndlist.count(i)>1]) gets all duplicate values in ndlist, and the rest of the list comprehension extracts the corresponding values in N where those values are found in ndlist
Suppose I have a dictionary with lists as follows:
{0: [31, 32, 58, 59], 1: [31, 32, 12, 13, 37, 38], 2: [12, 13]}
I am trying to obtain the following one from it:
{0: [1, 2, 3, 4], 1: [1, 2, 5, 6, 7, 8], 2: [5, 6]}
So I renumerate all the entries in order of occurence but skipping those that were already renumerated.
What I have now is a bunch of for loops going back and forth which works, but doesn't look good at all, could anyone please tell me the way it should be done in Python 2.7?
Thank you
import operator
data = {0: [31, 32, 58, 59], 1: [31, 32, 12, 13, 37, 38], 2: [12, 13]}
# the accumulator is the new dict with renumbered values combined with a list of renumbered numbers so far
# item is a (key, value) element out of the original dict
def reductor(acc, item):
(out, renumbered) = acc
(key, values) = item
def remapper(v):
try:
x = renumbered.index(v)
except ValueError:
x = len(renumbered)
renumbered.append(v)
return x
# transform current values to renumbered values
out[key] = map(remapper, values)
# return output and updated list of renumbered values
return (out, renumbered)
# now reduce the original data
print reduce(reductor, sorted(data.iteritems(), key=operator.itemgetter(0)), ({}, []))
If you're not worried about memory or speed you can use an intermediate dictionary to map the new values:
a = {0: [31, 32, 58, 59], 1: [31, 32, 12, 13, 37, 38], 2: [12, 13]}
b = {}
c = {}
for key in sorted(a.keys()):
c[key] = [b.setdefault(val, len(b)+1) for val in a[key]]
Just use a function like this:
def renumerate(data):
ids = {}
def getid(val):
if val not in ids:
ids[val] = len(ids) + 1
return ids[val]
return {k : map(getid, data[k]) for k in sorted(data.keys())}
Example
>>> data = {0: [31, 32, 58, 59], 1: [31, 32, 12, 13, 37, 38], 2: [12, 13]}
>>> print renumerate(data)
{0: [1, 2, 3, 4], 1: [1, 2, 5, 6, 7, 8], 2: [5, 6]}
data = {0: [31, 32, 58, 59], 1: [31, 32, 12, 13, 37, 38], 2: [12, 13]}
from collections import defaultdict
numbered = defaultdict(lambda: len(numbered)+1)
result = {key: [numbered[v] for v in val] for key, val in sorted(data.iteritems(), key=lambda item: item[0])}
print result