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/
Related
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.
I have two arrays of the same shape and now want to combine them by making every odd element and 0 one of the first array and every even one of the second array in the same order.
E.g.:
a = ([0,1,3,5])
b = ([2,4,6])
c = ([0,1,2,3,4,5,6])
I tried something including modulo to identify uneven indices:
a = ([0,1,3,5])
b = ([2,4,6])
c = a
i = 0
j = 2
l = 0
for i in range(1,22):
k = (i+j) % 2
if k > 0:
c = np.insert(c, i, b[l])
l+=1
else:
continue
I guess there is some easier/faster slicing option, but can't figure it out.
np.insert would work well:
>>> A = np.array([1, 3, 5, 7])
>>> B = np.array([2, 4, 6, 8])
>>> np.insert(B, np.arange(len(A)), A)
array([1, 2, 3, 4, 5, 6, 7, 8])
However, if you don't rely on sorted values, try this:
>>> A = np.array([5, 3, 1])
>>> B = np.array([1, 2, 3])
>>> C = [ ]
>>> for element in zip(A, B):
C.extend(element)
>>> C
[5, 1, 3, 2, 1, 3]
read the documentation of the range
for i in range(0,10,2):
print(i)
will print [0,2,4,6,8]
From what I understand, the first element in a is always first the rest are just intereleaved. If that is the case, then some clever use of stacking and reshaping is probably enough.
a = np.array([0,1,3,5])
b = np.array([2,4,6])
c = np.hstack([a[:1], np.vstack([a[1:], b]).T.reshape((-1, ))])
You could try something like this
import numpy as np
A = [0,1,3,5]
B = [2,4,6]
lst = np.zeros(len(A)+len(B))
lst[0]=A[0]
lst[1::2] = A[1:]
lst[2::2] = B
Even though I don't understand why you would make it so complicated
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)
I have a list a and I need to iterate from position 2 until its previous position 1.
# old index - 0 1 2 3 4
a = [1,2,3,4,5]
# new index - 2,3,4,0,1
# new value - 3,4,5,1,2
cnt = 0
while True:
for i in range(2,len(a)):
print(a[i])
for i in range(len(a)-2-1):
print(a[i])
break
I'm using 2 for loops but I believe there should be a better way to do it.
Let's assume we start with a list a = [1,2,3,4,5].
You can use collections.deque and its method deque.rotate:
from collections import deque
b = deque(a)
b.rotate(-2)
print(b)
deque([3, 4, 5, 1, 2])
Or, if you are happy to use a 3rd party library, you can use NumPy and np.roll:
import numpy as np
c = np.array(a)
c = np.roll(c, -2)
print(c)
array([3, 4, 5, 1, 2])
you can create a new list combining the elements after the particular value and before the particular value, let's say 3 in your case:
a = [1, 2, 3, 4, 5]
piv = a.index(3)
print(a[piv:] + a[:piv])
which gives you [3, 4, 5, 1, 2]
a = [1,2,3,4,5]
position = 2
for item in a[position:] + a[:position]:
print(item)
A base python based solution
a[2::] + a[:2:]
Gives
[3, 4, 5, 1, 2]
A generic version of the same would be
rotate_from = 2
a[rotate_from::] + a[:rotate_from:]
Write a function for rotate list,
In [114]: def rotate(lst, n):
...: return lst[-n:] + lst[:-n]
...:
In [115]: rotate(a,-2)
Out[115]: [3, 4, 5, 1, 2]
I have a simple, always-consecutive-ordered list like this:
all = [ 1, 2, 3, 4, 5, 6 ] # same as range( 1, 7 )
I also have current = 4. In the end I want the all list to look like this
altered = [ 1, 2, 5, 6 ]
So what happened was it removed the current number and the one before it 3.
current can also be 1 and 0, so I want to make sure it doesn't throw an error for those two values.
For the exception current = 0, the altered list is like this
altered = [ 1, 2, 3, 4, 5 ]
Which means that current = 0 simply removes the last number.
I feel like you can probably code something fancy with generators, but I suck at writing them.
Thanks in advance!
Bonus points for doing this in one line. If the current = 0 is too much trouble, then it could also be current = -1 or current = 7.
EDIT: Make sure to check for current = 1, which should be
altered = [ 2, 3, 4, 5, 6 ]
all = all[:max(current - 2, 0)] + all[current:]
or
del all[max(current - 2, 0):current]
Would this work?
>>> all = range(1, 7)
>>> new = all[:2]+all[4:]
>>> print new
[1, 2, 5, 6]
all[:max(current-2,0)] + all[max(current,0):][:-1] + all[-1:]*(0 < current < len(all))
>>> all = range(1,7)
>>> current = 4
>>> [item for item in all if item != current and item != current-1]
[1, 2, 5, 6]
>>> current = 0
>>> [item for item in all if item != current and item != current-1]
[1, 2, 3, 4, 5, 6]