create list with initialized results of variables instead of integer - python

I would like to know how I could create a list with defined variables.
I tried to create a loop but unfortunately, the content of the new list is only the integer of the variables instead of the value I’ve initialized before.
The result I want to reach is a list of the initialized values without the integer. I have had a result like (integer: value) but this is also not my target. I only want to have the initialized value in the list.
Code:
weight = {}
weight[0] = 16
weight[1] = 4
weight[2] = 12
weight[3] = 5
weight[4] = 9
weight[5] = 2
my_list = []
for i in weight:
my_list.append(i)
print(my_list)
output:
[0, 1, 2, 3, 4, 5]
target:
[16, 4, 12, 5, 9, 2]

What you are doing is initalizing a dictionary and iterating through the keys.
The solution would be:
weight = {}
weight[0] = 16
weight[1] = 4
weight[2] = 12
weight[3] = 5
weight[4] = 9
weight[5] = 2
my_list = []
for i in weight.values():
my_list.append(i)
print(my_list)
Or initalize the elements in an array:
weights = [16, 4, 12, 5, 9, 2]
print(weights)

Related

Search one smaller and one bigger number then serach term?

I have a list in the python and I want to find out the search term with conditions one smaller and one bigger number the search term.
list = [2, 3, 5, 7, 9, 12, 19, 22, 34]
search_term = 10
I want to get one smaller and one bigger term next to the search term from the list.
The expected result should be
output = [7, 9]
Edit for [7, 9]
Search up until you are >= search_term, then print last 2 values:
# Don't use class names (list) as variables
lst = [2, 3, 5, 7, 9, 12, 19, 22, 34]
search_term = 10
# Sort list for iterating. lst is now sorted
lst.sort()
index = 0
# Get index of values. Stop when item >= search_term
for i, item in enumerate(lst[1:]):
if item >= search_term:
index = i
break
output = [lst[index-1], lst[index]]
>>> output
[7, 9]
This was for printing value before and after search_term
There was no output, and this was a guess at what OP wanted
You can iterate over your lst and check for > and < search_term:
This works for non-empty lists
# Don't use class names (list) as variables
lst = [2, 3, 5, 7, 9, 12, 19, 22, 34]
search_term = 10
# Sort
lst.sort()
last = lst[0]
index = 0
# Get item before
for i, item in enumerate(lst[1:]):
if item < search_term:
last = item
index = i
else:
break
print(f'Before = {last}')
# Get item after
try:
for item in lst[index+1:]:
if item >= search_term:
last = item
break
except IndexError:
pass
# You don't have any values after the before value
print(f'After = {last}')
Before = 9
After = 12
An exception may be the case of:
>>> lst = [1, 10]
>>> search_term = 10
Which prints
Before = 1
After = 10
Code:
l = [2, 3, 5, 7, 9, 12, 19, 22, 34]
search_term = 10
tmp = [max([t for t in l if t <= search_term])] # smaller than search
tmp.append(min([t for t in l if t >= search_term])) #bigger than search
print("nearest smaller :",tmp[0])
print("nearest bigger :",tmp[1])
Output:
nearest smaller : 9
nearest bigger : 12

Python produce alternative numbers list from a list of n numbers

I have a list of n numbers. I want to group them in g groups. Also, I want to reverse elements in every odd group. Finally, I would combine all elements in even and odd groups into a new sublist. First I am giving what answer I am expecting and where I went wrong:
Expected answer:
num = 14
grp = 4
# A list of num natural numbers arranged in group (row) of 4 numbers
lst =
[0,1,2,3,
4,5,6,7,
8,9,10,11,
12,13]
lst =
[[0,1,2,3],
[4,5,6,7],
[8,9,10,11],
[12,13]]
# Reverse elements in odd rows
newlst =
[[0,1,2,3],
[7,6,5,4], # reversed here
[8,9,10,11],
[13,12]] # reversed here
# combine elements in all sublists by their position
# combine first element in all sublists into a new sublist
sollst =
[[0,7,8,13],[1,6,9,12],[2,5,10],[3,4,11]]
My solution:
num = 14
grp = 4
#### print
lst= list(range(0,num,1))
newlst= [lst[i:i+grp:1] for i in range(0,num,grp)]
evnlst = newlst[0::2]
oddlst = newlst[1::2]
newoddlst = [oddlst [i][::-1] for i in range(len(oddlst))]
sollst= evnlst + newoddlst
# This gives [[0, 1, 2, 3], [8, 9, 10, 11], [7, 6, 5, 4], [13, 12]]
from itertools import zip_longest
print([[x for x in t if x is not None] for t in zip_longest(fevngps)])
Present answer:
I reached the one step before the final answer and now I have to combine the lists of different lengths and I am running into an error
TypeError: 'int' object is not subscriptable
One approach:
from itertools import zip_longest
num = 14
grp = 4
lst = list(range(0, num, 1))
newlst = [lst[i:i + grp:1] for i in range(0, num, grp)]
# build new list where the sub-list are reversed if in odd indices
revlst = [lst[::-1] if i % 2 == 1 else lst for i, lst in enumerate(newlst)]
# zip using zip_longest and filter out the None values (the default fill value of zip_longest)
result = [[v for v in vs if v is not None] for vs in zip_longest(*revlst)]
print(result)
Output
[[0, 7, 8, 13], [1, 6, 9, 12], [2, 5, 10], [3, 4, 11]]

Python adding a list to a slice of another list

Here's basic problem:
>>> listb = [ 1, 2, 3, 4, 5, 6, 7 ]
>>> slicea = slice(2,5)
>>> listb[slicea]
[3, 4, 5]
>>> lista = listb[slicea]
>>> lista
[3, 4, 5]
>>> listb[slicea] += lista
>>> listb
[1, 2, 3, 4, 5, 3, 4, 5, 6, 7]
listb should be
[1, 2, 6, 8, 10, 6, 7]
But 3, 4, 5 was inserted after 3, 4, 5 not added to it.
tl;dr
I have this code that's not working:
self.lib_tree.item(song)['values'][select_values] = adj_list
self.lib_tree.item(album)['values'][select_values] += adj_list
self.lib_tree.item(artist)['values'][select_values] += adj_list
The full code is this:
def toggle_select(self, song, album, artist):
# 'values' 0=Access, 1=Size, 2=Selected Size, 3=StatTime, 4=StatSize,
# 5=Count, 6=Seconds, 7=SelSize, 8=SelCount, 9=SelSeconds
# Set slice to StatSize, Count, Seconds
total_values = slice(4, 7) # start at index, stop before index
select_values = slice(7, 10) # start at index, stop before index
tags = self.lib_tree.item(song)['tags']
if "songsel" in tags:
# We will toggle off and subtract from selected parent totals
tags.remove("songsel")
self.lib_tree.item(song, tags=(tags))
# Get StatSize, Count and Seconds
adj_list = [element * -1 for element in \
self.lib_tree.item(song)['values'][total_values]]
else:
tags.append("songsel")
self.lib_tree.item(song, tags=(tags))
# Get StatSize, Count and Seconds
adj_list = self.lib_tree.item(song)['values'][total_values] # 1 past
self.lib_tree.item(song)['values'][select_values] = adj_list
self.lib_tree.item(album)['values'][select_values] += adj_list
self.lib_tree.item(artist)['values'][select_values] += adj_list
if self.debug_toggle < 10:
self.debug_toggle += 1
print('artist,album,song:',self.lib_tree.item(artist, 'text'), \
self.lib_tree.item(album, 'text'), \
self.lib_tree.item(song, 'text'))
print('adj_list:',adj_list)
The adj_list has the correct values showing up in debug.
How do I add a list of values to the slice of a list?
The behavior you want is not a feature of any Python built-in type; + with built-in sequences means concatenation, not element-wise addition. But numpy arrays will do what you want, so I'd suggest looking into numpy. Simple example:
>>> import numpy as np
>>> a = np.array([2,3,4], dtype=np.int64)
>>> b = np.array([5,6,7], dtype=np.int64)
>>> a += b
>>> a
array([ 7, 9, 11])
>>> print(a)
[ 7 9 11]
>>> print(a.tolist())
[7, 9, 11]
Note that the output (both repr and str forms) looks a little different from Python lists, but you can convert back to a plain Python list if needed.

Split an array inside another in Python

I am trying to write a code that compares two arrays ('a' and 'b)' and do something like that, getting the 'c' array:
a = [1, 2, 2, 3, 3, 5]
b = [1, 2, 3] (It is taken from 'a' randomly)
c = [2, 3, 5]
The problem I have is very simple since the algorithm is ok.
The code I am using is:
vetor1 = [1, 2, 2, 3, 3, 5]
vetor2 = sorted(random.sample(vetor1, 3))
inter = np.intersect1d(vetor1, vetor2)
cont_array2 = []
for i in range(len(inter)):
cont2 = 0
for j in range(len(vetor2)):
if inter[i]==vetor2[j]:
cont2 = cont2 + 1
cont_array2.append(cont2)
cont_array1 = []
for i in range(0,len(inter),1):
cont1 = 0
for j in range(0, len(vetor1), 1):
if inter[i]==vetor1[j]:
cont1 = cont1 + 1
cont_array1.append(cont1)
n_elements = np.subtract(cont_array1, cont_array2)
vetor2_1 = []
for i in range(len(n_elements)):
if n_elements[i]!=0:
vetor2_1.append(inter[i]*np.ones(n_elements[i]))
vetor2_2 = []
for data1 in vetor1:
if data1 not in inter:
vetor2_2.append(data1)
vetor3 = sorted(vetor2_1 + vetor2_2)
print(vetor3)
The result I am getting is:
[array([2.]), array([3.]), 5]
I imagine the problem is in:
vetor2_1.append(inter[i]*np.ones(n_elements[i]))
Because:
print(vetor2_1)
Gives me:
[array([2.]), array([3.])]
What should I do since I am not receving as answer [2, 3, 5]?
IIUC, you can turn all your algorithm into one line:
a = [1, 2, 2, 3, 3, 5]
b = [1, 2, 3]
c = [a.pop(a.index(i)) for i in b] #Works even with strings.
Output:
[2, 3, 5]
If you need to parametrize something, you can turn it into a function. This will work with sorted(random.sample(vetor1, 3)), but I didn't use it for replicability.
//generating a random index for array a, to take 3 elements out of it
my_random_int = random.randint(0,len(a)-2)
//popping the element out of the array to put them in b
for x in range(0,2):
b[x]=a.pop(my_random_int+x)
sources:
https://www.programiz.com/python-programming/methods/list/pop
https://www.edureka.co/blog/generate-random-number-in-python/

Generate random array of integers with a number of appearance of each integer

I need to create a random array of 6 integers between 1 and 5 in Python but I also have another data say a=[2 2 3 1 2] which can be considered as the capacity. It means 1 can occur no more than 2 times or 3 can occur no more than 3 times.
I need to set up a counter for each integer from 1 to 5 to make sure each integer is not generated by the random function more than a[i].
Here is the initial array I created in python but I need to find out how I can make sure about the condition I described above. For example, I don't need a solution like [2 1 5 4 5 4] where 4 is shown twice or [2 2 2 2 1 2].
solution = np.array([np.random.randint(1,6) for i in range(6)])
Even if I can add probability, that should work. Any help is appreciated on this.
You can create an pool of data that have the most counts and then pick from there:
import numpy as np
a = [2, 2, 3, 1, 2]
data = [i + 1 for i, e in enumerate(a) for _ in range(e)]
print(data)
result = np.random.choice(data, 6, replace=False)
print(result)
Output
[1, 1, 2, 2, 3, 3, 3, 4, 5, 5]
[1 3 2 2 3 1]
Note that data is array that has for each element the specified count, then we pick randomly from data this way we ensure that you won't have more elements that the specify count.
UPDATE
If you need that each number appears at least one time, you can start with a list of each of the numbers, sample from the rest and then shuffle:
import numpy as np
result = [1, 2, 3, 4, 5]
a = [1, 1, 2, 0, 1]
data = [i + 1 for i, e in enumerate(a) for _ in range(e)]
print(data)
result = result + np.random.choice(data, 1, replace=False).tolist()
np.random.shuffle(result)
print(result)
Output
[1, 2, 3, 3, 5]
[3, 4, 2, 5, 1, 2]
Notice that I subtract 1 from each of the original values of a, also the original 6 was change to 1 because you already have 5 numbers in the variable result.
You could test your count against a dictionary
import random
a = [2, 2, 3, 1, 2]
d = {idx: item for idx,item in enumerate(a, start = 1)}
l = []
while len(set(l) ^ set([*range(1, 6)])) > 0:
l = []
while len(l) != 6:
x = random.randint(1,5)
while l.count(x) == d[x]:
x = random.randint(1,5)
l.append(x)
print(l)

Categories