Operate on a list and replace values - python

I have the list called 'list_one', which I seek to relate to 'list_relation', to finally have a final list of values, my logic is as follows:
By looping in the range of 'list_one' and for each 'items_relation' of 'list_relation':
1.If 'list_one [i] [0]' is inside 'items_relation', I add the corresponding operation of 'list_one'.
list_one = [[1, 0],
[2, 0],
[3, 0],
[4, 0],
[11, 0],
[12, 0],
[13, 2000],
[14, 3000],
[15, 3500],
[16, 5000],
[17, 6500],
[18, 8800],
[19, 6700],
[20, 280]]
# Code to get this 'list_relation' ...
list_relation = [[13, 14], [15, 16],
[17, 18], [19, 20]]
final = []
for i in range(len(list_one)):
for items_elements in list_relation:
for k in items_elements:
if list_one[i][0] in items_elements:
final.append((list_one[i][1] + list_one[i][0]))
print(final)
I am looking for a list like this:
[[2013, 3014], [3515, 5016], [6517, 8818], [6719, 300]]
What is the best way to do it? Thank you.

list_one appears to be a lookup table - it would make more sense to use a dictionary instead of a list. Then loop through the values of list_relation, do a lookup against the dictionary and add the value if it is there. If it isn't there, get a default value of 0 so it doesn't affect the sum. This also means there is no need to include lookup entries with values of 0:
list_one = {13: 2000, # note choose a better var name
14: 3000,
15: 3500,
16: 5000,
17: 6500,
18: 8800,
19: 6700,
20: 280,}
list_relation = [[13, 14],
[15, 16],
[17, 18],
[19, 20]]
final = [[item + list_one.get(item, 0)
for item in pair]
for pair in list_relation]

You can build a dictionary from list_one and then iterate to create the resulting list.
>>> d = dict(list_one)
>>> final = [[el+d[el] for el in l] for l in list_relation]
>>> final
[[2013, 3014], [3515, 5016], [6517, 8818], [6719, 300]]

Related

Seperate array into three new arrays using inequalities in Python

I am trying to split an array into three new arrays using inequalities.
This will give you an idea of what I am trying to achieve:
measurement = [1, 5, 10, 13, 40, 43, 60]
for x in measurement:
if 0 < x < 6:
small = measurement
elif 6 < x < 15:
medium = measurement
else
large = measurement
Intended Output:
small = [1, 5]
medium = [10, 13]
large = [40, 43, 60]
If your array is sorted, you can do :
measurement = [1, 5, 10, 13, 40, 43, 60]
one_third = len(measurement) // 3
two_third = (2 * len(measurement)) // 3
small = measurement[:one_third]
medium = measurement[one_third : two_thirds]
large = measurement[two_thirds:]
You could easily generalize to any number of split with a loop. Not sure if you wanted explicitly those inequalities or just split with the array in three. If its the first one, my answer is not right
You can use numpy:
arr = np.array(measurement)
small = arr[(arr>0)&(arr<6)] # array([1, 5])
medium = arr[(arr>6)&(arr<15)] # array([10, 13])
large = arr[(arr>15)] # array([40, 43, 60])
You can also use dictionary:
d = {'small':[], 'medium':[], 'large':[]}
for x in measurement:
if 0 < x < 6:
d['small'].append(x)
elif 6 < x < 15:
d['medium'].append(x)
else:
d['large'].append(x)
Output:
{'small': [1, 5], 'medium': [10, 13], 'large': [40, 43, 60]}
With the bisect module you can do something along these lines:
from bisect import bisect
breaks=[0,6,15,float('inf')]
buckets={}
m = [1, 5, 10, 13, 40, 43, 60]
for e in m:
buckets.setdefault(breaks[bisect(breaks, e)], []).append(e)
You then have a dict of lists matching what you are looking for:
>>> buckets
{6: [1, 5], 15: [10, 13], inf: [40, 43, 60]}
You can also form tuples of your break points and list that will become a dict to form the sub lists:
m = [1, 5, 10, 13, 40, 43, 60]
buckets=[('small',[]), ('medium',[]), ('large',[]), ('other',[])]
breaks=[(0,6),(6,15),(15,float('inf'))]
for x in m:
buckets[
next((i for i,t in enumerate(breaks) if t[0]<=x<t[1]), -1)
][1].append(x)
>>> dict(buckets)
{'small': [1, 5], 'medium': [10, 13], 'large': [40, 43, 60], 'other': []}

Accessing elements of a list within a dictionary component wise

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!

How do you find most duplicates in a 2d list?

I have a 2d list that i would like to return the most duplicates by using a list comprehension. For example, i have a list below
a = [[10, 15, 17,],[20,21,27],[10,15,17],[21,27,28],[21,27,28],[5,10,15],[15,17,20]]
I would like my result to be
b = [[10,15,17],[21,27,28]
The common solution for counting repetitions is collections.Counter:
from collections import Counter
a = [[10, 15, 17], [20, 21, 27], [10, 15, 17], [21, 27, 28], [21, 27, 28], [5, 10, 15], [15, 17, 20]]
# count duplicates
counts = Counter(map(tuple, a))
# find the maximum count (the values of counts are the duplicate count)
maximum_count = max(counts.values())
# filter and convert back to list
result = [list(e) for e, count in counts.items() if count == maximum_count]
print(result)
Output
[[10, 15, 17], [21, 27, 28]]
In your case in particular as the elements of the list are list, you need to convert them to tuples (to make them hashable), then just filter the list and keep the elements with maximum count.
One line splitted here:
[ a[k]
for k in range(len(a))
if a.count( a[k] ) > 1
and k == a.index( a[k] ) ]
The simplest way to do this to find the count for each element, and store the maximum count. Then, display all elements that have the maximum count (removing duplicates).
The below code will work for you:
a = [[10, 15, 17,],[20,21,27],[10,15,17],[21,27,28],[21,27,28],[5,10,15],[15,17,20]]
check=0
for i in a:
if a.count(i) > check:
check=a.count(i) #Check to see maximum count
b=[]
for i in a:
if a.count(i) == check: #Choosing elements with maximum count
if i not in b: #Eliminating duplicates
b.append(i)
print(b)
Output:
[[10, 15, 17], [21, 27, 28]]

Trying to add lists of lists to an empty dictionary in a for loop, but the entries are being completely overwritten in every iteration

Novice with programming in general here. I have an empty dictionary with no number of keys, (where no in this case = 3). I'm trying to generate a list of lists that will be added to the dictionary within a loop, but over each loop the other keys are being overwritten. See my attempt below:
#generating dictionary for all fibres with number n
fibre = {i : {}for i in range(no)}
#generating empty fibre of size n_f
fibre_e = [[[] for i in range(n_f)] for j in range(n_f)]
rand_r = [[] for a in range(no)]
rand_c = [[] for a in range(no)]
#generating fibre element from random corner elements
for a in range(no):
# choosing a random corner element
fibre[a] = fibre_e
rand_r[a] = randrange(len(all_e))
rand_c[a] = randrange(len(all_e))
for i in range(n_f):
e1_fibre=all_e[rand_r[a]][rand_c[a]]
#move to upper row
rand_r[a] += 1
for j in range(n_f):
fibre_e[i][j] = e1_fibre
e1_fibre += 1
print(fibre)
This is the output when I checked the progression:
{0: [[57, 58], [66, 67]], 1: {}, 2: {}}
{0: [[33, 34], [42, 43]], 1: [[33, 34], [42, 43]], 2: {}}
{0: [[29, 30], [38, 39]], 1: [[29, 30], [38, 39]], 2: [[29, 30], [38, 39]]}
For context, this is to generate an abaqus mesh file with a random distribution of identical fibre elements within a matrix.
edit:context
Using copy.deepcopy worked
for a in range(no):
# choosing a random corner element
rand_r[a] = randrange(len(all_e))
rand_c[a] = randrange(len(all_e))
for i in range(n_f):
e1_fibre=all_e[rand_r[a]][rand_c[a]]
#move to upper row
rand_r[a] += 1
for j in range(n_f):
fibre_e[i][j] = e1_fibre
e1_fibre += 1
fibre[a] = copy.deepcopy(fibre_e)
print(fibre)
Output:
{0: [[68, 69], [77, 78]], 1: {}, 2: {}}
{0: [[68, 69], [77, 78]], 1: [[6, 7], [15, 16]], 2: {}}
{0: [[68, 69], [77, 78]], 1: [[6, 7], [15, 16]], 2: [[28, 29], [37, 38]]}
Specifically in your case, just assign the expression you're assigning to fibre_e to fibre[a] instead. Then new lists get created for each iteration. (You don't need the variable fibre_e then at all.)

Replacing items in a two dimensional list in python

I am trying to append the second item in my two dimensional.
I have tried a few dozen different ways and can't seem to get it to append.
def main():
values = [[10,0], [13, 0], [36, 0], [74,0], [22,0]]
user = int(input('Enter a whole number'))
for i in range(len(values)):
print(values[i])
(current out put)
10, 0
13, 0
36, 0
74, 0
22, 0
(were the second part it is values[0] + user input)
[10, 12]
[13, 15]
[36, 38]
[74, 76]
[22, 24]
with list comprehension
user = 2
[[x[0], sum(x)+user] for x in values]
>>> [[10, 12], [13, 15], [36, 38], [74, 76], [22, 24]]
or using map:
map(lambda x: [x[0], sum(x)+user], values)
First, you can nearly always avoid iterating over range(len(iterable)) - in this case, your loop can be written as the much nicer:
for value in values:
print(value)
for exactly the same functionality.
I'm not sure from your description exactly how you want the code to behave, but it seems like you want something like this - each line of output will have the first item of the corresponding value, and then that added to the user input; ie, ignoring the second item of the existing input entirely:
for value in values:
total = value[0] + user
print((value[0], total))
or if you want it to overwrite the second item of each value for later use in your program:
values = [[10,0], [13, 0], [36, 0], [74,0], [22,0]]
for value in values:
value[1] = value[0] + user
print(value)
Shouldn't it be just like this?
>>> def f():
values = [[10,0], [13, 0], [36, 0], [74,0], [22,0]]
user = int(input('Enter a whole number'))
for i in range(len(values)):
values[i][1]=values[i][0]+user
print(values[i])
>>> f()
Enter a whole number2
[10, 12]
[13, 15]
[36, 38]
[74, 76]
[22, 24]

Categories

Resources