This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 16 days ago.
I have a list of rect objects which is randomly generated and i want to take a specific element out of the list with .remove(), how would I be able to do something like that? Here's the snippet:
map = [(x, y) for x in range(0,20) for y in range(0,20)]
def cellGen():
global mObj
xr = random.randint(1,21)
yr = random.randint(1,21)
tp = (xr,yr)
if tp in map:
cell = pygame.Rect(tp\[0\]\*20, tp\[1\]\*20, 20, 20)
pygame.draw.rect(window, (0,0,0), cell)
mObj.append(cell)
.
.
.
#k2 is a set of dictionary keys in a list; valCel is all the valid rectangles' coordinates (tuples )in a list
for values in k2:
if (values[0],values[1]) in valCel:
valCel.remove((values[0],values[1]))
#if (values[0],values[1]) in mObj:
mObj.remove((values[0],values[1],20,20))
ValueError: list.remove(x): x not in list
here's mObj's output:
[<rect(300, 200, 20, 20)>, <rect(160, 300, 20, 20)>, <rect(380, 120, 20, 20)>, <rect(300, 300, 20, 20)>, <rect(60, 140, 20, 20)>, <rect(100, 20, 20, 20)>, <rect(100, 140, 20, 20)>, <rect(80, 280, 20, 20)>, <rect(320, 380, 20, 20)>, <rect(40, 380, 20, 20)>, <rect(220, 160, 20, 20)>, <rect(140, 200, 20, 20)>, <rect(40, 20, 20, 20)>, <rect(240, 120, 20, 20)>, <rect(100, 220, 20, 20)>, <rect(200, 200, 20, 20)>, <rect(40, 240, 20, 20)>, <rect(100, 40, 20, 20)>, <rect(380, 20, 20, 20)>, <rect(320, 220, 20, 20)>, <rect(60, 260, 20, 20)>, <rect(60, 20, 20, 20)>, <rect(360, 40, 20, 20)>, <rect(360, 320, 20, 20)>, <rect(40, 260, 20, 20)>, <rect(220, 20, 20, 20)>, <rect(160, 140, 20, 20)>, <rect(160, 380, 20, 20)>, <rect(100, 240, 20, 20)>, <rect(300, 260, 20, 20)>, <rect(180, 380, 20, 20)>, <rect(380, 380, 20, 20)>, <rect(240, 60, 20, 20)>, <rect(60, 40, 20, 20)>, <rect(100, 60, 20, 20)>, <rect(160, 260, 20, 20)>, <rect(360, 300, 20, 20)>, <rect(300, 40, 20, 20)>, <rect(160, 360, 20, 20)>, <rect(40, 140, 20, 20)>, <rect(280, 380, 20, 20)>, <rect(380, 60, 20, 20)>]
How would i be able to take <rect(40, 140, 20, 20)> out of the list without calling the index of the element?
The objects in list are of the type pygame.Rect so you have to pass the right object type to it be found.
I suggest check if object is in list before call the remove function also.
for values in k2:
if (values[0],values[1]) in valCel:
valCel.remove((values[0],values[1]))
object = pygame.Rect(values[0], values[1], 20, 20)
if object in mObj:
mObj.remove(object)
Related
i have some array
`
arr_values = [[71, 70, 80, 80, 50, 90, 100, 85, 75], [70, 70, 80, 80, 50, 50, 100, 85, 75], [70, 70, 80, 80, 50, 90, 100, 85, 78]],
[[70, 70, 80, 80, 50, 90, 100, 85, 75], [70, 70, 80, 80, 50, 50, 100, 85, 75], [70, 70, 80, 80, 50, 90, 100, 85, 79]],
[[70, 70, 80, 80, 50, 90, 100, 85, 75], [70, 70, 80, 80, 50, 50, 100, 85, 75], [70, 70, 80, 80, 50, 90, 100, 85, 80]],
[[70, 70, 80, 80, 50, 90, 100, 85, 75], [70, 70, 80, 80, 50, 50, 100, 85, 75], [70, 70, 80, 80, 50, 90, 100, 85, 81]],
[[70, 70, 80, 80, 50, 90, 100, 85, 73], [70, 70, 80, 80, 50, 50, 100, 85, 74], [70, 70, 80, 80, 50, 90, 100, 85, 76], [70, 70, 80, 80, 50, 90, 100, 82, 73]]
`
i want it become like this
`
[[701] [660] [703]]
[[700] [660] [704]]
[[700] [660] [705]]
[[700] [660] [706]]
[[698] [659] [701] [695]]
`
i have try with this way
`
for values in arr_values:
for value in range(len(values)):
a=0
for a in values[value]:
a += a
print(a)
`
the result is not what i want. how to loop correctly?
`
for values in arr_values:
for value in range(len(values)):
a=0
for a in values[value]:
a += a
print(a)
`
the result is not what i want. how to loop correctly?
If you want to return a list of sums, do it by creating an empty list and then appending each sum iteratively.
arraySums = []
for subArray in arr_values:
arrays = []
for array in subArray:
curSum = 0
for elem in array:
curSum += elem
arrays.append([curSum])
arraySums.append(arrays)
Note: arr_values is a tuple of lists
Explanation: Create a list that will hold the result of everything outside of the loop so you can store the results. After that, iterate over the arr_values tuple to get the 2d lists you'll be summing. The inner two for loops are then the sum of a 2 dimensional list, appended to the master list after.
The following code partitions a list in spaces of 5.
o_list = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]
def partition(lst, size):
for i in range(0, len(lst), size):
yield lst[i :: size]
# size of each partition
n = 5
p_list = list(partition(o_list, n))
print("Original List: ")
print(o_list)
print("Partitioned List:")
print(p_list)
The following are the results:
Original List:
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]
Partitioned List:
[[10, 60, 110, 160], [60, 110, 160], [110, 160], [160]]
However I want the second array to be [20, 70, 120, 170] and the third and so on follow suit.
Just replace the comma in the range function to a // operator:
o_list = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]
def partition(lst, size):
for i in range(0, len(lst) // size):
yield lst[i :: size]
# size of each partition
n = 5
p_list = list(partition(o_list, n))
print("Original List: ")
print(o_list)
print("Partitioned List:")
print(p_list)
This prints:
Original List:
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]
Partitioned List:
[[10, 60, 110, 160], [20, 70, 120, 170], [30, 80, 130, 180], [40, 90, 140, 190]]
Something like this?
o_list = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]
[o_list[x::5] for x in range(len(o_list)//5)]
[[10, 60, 110, 160],
[20, 70, 120, 170],
[30, 80, 130, 180],
[40, 90, 140, 190]]
With division you can figure out how many slices can be produced, then simply produce those slices in a loop.
partition = lambda L, N: [L[n::N] for n in range(len(L)//N)]
print(partition(list(range(10, 201, 10)), 5))
#[[10, 60, 110, 160], [20, 70, 120, 170], [30, 80, 130, 180], [40, 90, 140, 190]]
I wanted to create a random array with the lenght of 24 in python, by assigning the values of a list seq=[30,170]. So I wanted to have an array which looks like a=[30,30,30,170,30,170,...]. The problem is, that the values shouldn't be assigned completely random, but with a certain probability. In this case, if the first value is 30 (or 170) the probability of the next value to be 30 (or 170) as well, should be 90% and the probability of the next value to be 170 (or 30) should be 10%.
Does anyone know how to do this? For the moment I only found how to arrange them randomly. Thanks!!
import random
seq=[30,170]
a = random.choices(seq,k=24)
You can provide weights to random.choices(population, weights=None, *, cum_weights=None, k=1).
You need to do it iteratively to be able to reference the last value when looking up weight you need to use:
import random
seq = [30, 170]
# weight lookup
wgt = {30: (90, 10), 170:(10, 90)}
r = []
for _ in range(24):
if not r:
# need some initial value: 50/50
r.append(random.choice(seq))
else:
# k == 1, using correct weights from lookup, use only single value and add it
r.append(random.choices(seq, weights=wgt[r[-1]], k=1)[0])
print(r)
Output over 8 runs:
[170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170]
[30, 30, 30, 30, 30, 30, 170, 170, 170, 170, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]
[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]
[30, 30, 30, 30, 30, 170, 170, 170, 170, 170, 170, 170, 170, 30, 30, 170, 170, 170, 170, 170, 170, 170, 170, 170]
[170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 30, 30, 30, 170, 170, 170, 170]
[170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 30, 30, 30, 30, 30, 30, 30, 30, 30]
[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]
[30, 30, 170, 170, 30, 170, 170, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]
You can also provide the weighting yourself:
seq = [30,170]
w = {30: (30,30,30,30,30,30,30,30,30,170), # if 30: use 9 * 30 + 1 * 170
170:(30,170,170,170,170,170,170,170,170,170)} # if 170: use 9 * 170 + 1 * 30
r = []
for _ in range(24):
if not r:
r.append(random.choice(seq))
else:
r.append(random.choice(w[r[-1]]))
I have the following box plot which plots some values with different mean and median values for each box; I am wondering if there is any way to label them so that they appear on the graph legend (because the current box plot plots an orange line for the median and a blue dot for the mean and it is not so clear which is which)? Also is there a way to make one legend for these subplots, instead of having a legend for each one, since they are essentially the same objects just different data?
Here's a code example for one of the subplots, the other subplots are the same but have different data:
fig = plt.figure()
xlim = (4, 24)
ylim = (0, 3700)
plt.subplot(1,5,5)
x_5_diff = {5: [200, 200, 291, 200, 291, 200, 291, 200, 291, 200, 291, 200, 291, 200, 291],
7: [161, 161, 179, 161, 179, 161, 179, 161, 179, 161, 179, 161, 179, 161, 179],
9: [205, 205, 109, 205, 109, 205, 109, 205, 109, 205, 109, 205, 109, 205, 109],
11: [169, 169, 95, 169, 95, 169, 95, 169, 95, 169, 95, 169, 95, 169, 95],
13: [43, 43, 70, 43, 70, 43, 70, 43, 70, 43, 70, 43, 70, 43, 70],
15: [33, 33, 39, 33, 39, 33, 39, 33, 39, 33, 39, 33, 39, 33, 39],
17: [23, 23, 126, 23, 126, 23, 126, 23, 126, 23, 126, 23, 126, 23, 126],
19: [17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17],
21: [15, 15, 120, 15, 120, 15, 120, 15, 120, 15, 120, 15, 120, 15, 120],
23: [63, 63, 25, 63, 25, 63, 25, 63, 25, 63, 25, 63, 25, 63, 25]}
keys = sorted(x_5_diff)
plt.boxplot([x_5_diff[k] for k in keys], positions=keys) # box-and-whisker plot
plt.hlines(y = 1600, colors= 'r', xmin = 5, xmax = 23, label = "Level 1 Completed")
plt.title("x = 5 enemies")
plt.ylim(0,3700)
plt.plot(keys, [sum(x_5_diff[k]) / len(x_5_diff[k]) for k in keys], '-o')
plt.legend()
plt.show()
Any help would be appreciated.
Its a bit late, but try this:
bp = plt.boxplot([x_5_diff[k] for k in keys], positions=keys)
# You can access boxplot items using ist dictionary
plt.legend([bp['medians'][0], bp['means'][0]], ['median', 'mean'])
Store the mean as a separate vector. Loop over the vectors to plot.
(Will try to give implementation, as soon as I have my laptop)
Say I have a list of heights that a measurement were taken from:
[0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0, 10.5, 11.0, 11.5, 12.0, 12.5, 13.0, 13.5, 14.0, 14.5, 15.0, 15.5, 16.0, 16.5, 17.0, 17.5]
And I have a 2d list of angles that the data were taken from (from off vertical),
[[], [20, 50], [0, 10, 20, 30, 40, 50, 320, 330, 340, 350], [0, 10, 20, 30, 40, 330, 340, 350], [0, 10, 20, 30, 40, 50, 310, 320, 340], [0, 10, 20, 30, 40, 50, 60, 300, 310, 330, 340, 350], [0, 20, 30, 50, 60, 70, 310, 320, 330, 340, 350], [0, 10, 20, 40, 110, 320, 330, 340, 350], [0, 10, 20, 150, 300, 310, 320, 330, 340, 350], [0, 10, 20, 140, 180, 190, 310, 320, 330, 340], [10, 20, 30, 40, 150, 180, 340], [0, 140, 180, 320], [130, 140, 180, 190], [130, 180, 190], [190, 200], [180, 190], [170, 180, 190], [160, 170, 180, 190], [150, 160, 330, 340], [160, 170, 190, 350], [170, 190], [170], [190], [180], [160], [340], [20, 30, 40, 290, 330], [0, 20, 40, 60, 340], [], [], [], [0], [10, 20, 200, 230, 290], [10, 180, 190, 200, 210, 240, 340, 350], [30, 220]
(set of lists correlates to the heights in the first list, so blank entries mean no measurements were taken at the corresponding height). I want to plot the angle on the x axis, and the height on the y axis. However, for each point, I also want to plot a slope that has been calculated earlier (not the slope of the previous two lists). This slope list is in the exact same format as the list of angles, and I would like to plot it as a colour density. The slopes are generally between -1 and 1, and they show the correlation. I am essentially searching for the slope of two variables, per angle, per time.
This is what I have so far, but am having trouble figuring out how to plot the slope.
for x in range(0, len(height)):
height_temp = np.linspace(height[x], height[x], len(angle[x]))
plt.scatter(angle[x], height_temp, s = slope[x])
plt.show()
Any help would be appreciated!!
Here's what you need:
plt.scatter(angle[x], height_temp, c=slope[x], s=slope[y], cmap='rainbow')
You're probably going to want to consider setting vmin and vmax as well.