Related
I am writing code to make a bot for the math game "Dandelions" and in order to do so, I take all columns, rows, and diagonals that contain the number 1. Then, with this list of lists that contain the number 1, I need to separate them using a for loop. However, when running this for loop I get an error saying that the pop index is out of range, but when I run the code with each individual i value, I don't get an error. It is the last for loop at the very end of the code that is causing this problem. Please help! Note: Even when running the for loop with a range of 3, it still outputs an error. Only indexes 0 and 2 are outputted.
row_1 = [0, 0, 0, 0, 0]
row_2 = [0, 1, 0, 0, 0]
row_3 = [0, 0, 0, 0, 0]
row_4 = [0, 0, 0, 0, 0]
row_5 = [0, 0, 0, 0, 0]
col_1 = [0, 0, 0, 0, 0]
col_2 = [0, 0, 1, 0, 0]
col_3 = [0, 0, 0, 0, 0]
col_4 = [0, 0, 0, 0, 0]
col_5 = [0, 0, 0, 0, 0]
#diagonals 1-9 go from left to right, while diagonals 10-18 go from right to left
dia_1 = [0]
dia_2 = [0, 0]
dia_3 = [0, 0, 0]
dia_4 = [0, 0, 0, 0]
dia_5 = [0, 0, 0, 1, 0]
dia_6 = [0, 0, 0, 0,]
dia_7 = [0, 0, 0]
dia_8 = [0, 0]
dia_9 = [0]
dia_10 = [0]
dia_11 = [0, 0]
dia_12 = [0, 0, 0]
dia_13 = [0, 0, 0, 0]
dia_14 = [0, 0, 0, 0, 1]
dia_15 = [0, 0, 0, 0,]
dia_16 = [0, 0, 0]
dia_17 = [0, 0]
dia_18 = [0]
dia = [dia_1, dia_2, dia_3, dia_4, dia_5, dia_6,
dia_7, dia_8, dia_9, dia_10, dia_11, dia_12,
dia_13, dia_14, dia_15, dia_16, dia_17, dia_18]
row = [row_1, row_2, row_3, row_4, row_5]
col = [col_1, col_2, col_3, col_4, col_5]
possible = []
for i in dia:
if 1 in i:
possible.append(i)
for i in row:
if 1 in i:
possible.append(i)
for i in col:
if 1 in i:
possible.append(i)
for i in range(0, 4):
print(possible.pop(i))
The for loops that are giving you the out-of-range error wrap them on a try-except block, in the exception add new logic to ignore or fix the out of range; for instance:
try:
for i in range(0, 4):
print(possible.pop(i))
except:
#correct your out-of-range:
pass
Seems you did not get my hint and the only answer so far is not very helpful.
To reproduce the problem, let's hard-code possible, since everything before the last loop does not really matter.
possible = [[0, 0, 0, 1, 0], [0, 0, 0, 0, 1], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0]]
print(f"Possible before loop: {possible}")
for i in range(0, 4):
print(f"Item at pos {i}: {possible.pop(i)}")
print(f"Possible after pop: {possible}")
Output:
Possible before loop: [[0, 0, 0, 1, 0], [0, 0, 0, 0, 1], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0]]
Item at pos 0: [0, 0, 0, 1, 0]
Possible after pop: [[0, 0, 0, 0, 1], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0]]
Item at pos 1: [0, 1, 0, 0, 0]
Possible after pop: [[0, 0, 0, 0, 1], [0, 0, 1, 0, 0]]
Traceback (most recent call last):
File "test.py", line 5, in <module>
print(f"Item at pos {i}: {possible.pop(i)}")
IndexError: pop index out of range
Explanation:
As I said before, i keeps increasing, but at the same time, you are removing items from possible.
After the first iteration possible is [[0, 0, 0, 0, 1], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0]].
But during the next (the second) iteration, you are popping the item at index 1, which is [0, 1, 0, 0, 0] - you were probably expecting [0, 0, 0, 0, 1].
During the third iteration, possible only holds two items: [[0, 0, 0, 0, 1], [0, 0, 1, 0, 0]] but you are trying to pop the item at index 2, which is when the pop index out of range error happens.
Why not simple iterate your list and print the items instead of popping them?
possible = [[0, 0, 0, 1, 0], [0, 0, 0, 0, 1], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0]]
for item in possible:
print(item)
Output:
[0, 0, 0, 1, 0]
[0, 0, 0, 0, 1]
[0, 1, 0, 0, 0]
[0, 0, 1, 0, 0]
I have a nested loop data=
[[1,43,344,546],[2,34,45,565]....[10,1,1,1],
[1,15,111,151],[2,152,28,19]....[10,2,2,2],
[1,21,45,1647],[2,288,65,90]....[10,3,3,3]
.....]
so basically, all the inside lists can be grouped by 10lists with the first element always starting from 1 to 10. taking the every 10th list as a key, so I want to calculate a newlist by subtracting every list's number by the 10th list accordingly, for example
[[1,43-1,344-2,546-3], [2,34-1,45-2,565-3].... [10,1,2,3],
[1,15-21,111-22,151-23],[2,152-21,28-22,19-23]....[10,21,22,23],
[1,21-31,45-32,1647-33],[2,288-31,65-32,90-33]....[10,31,32,33]
.....]
My code seems don't work, can someone plz help with this? thanks
line = 0
while line <= (len(data) - 10):
for i in range(line, line + 10):
temp = data[i]
if temp[0] == 10: #find the every 10 th keys and store them to x, y, z
x = temp[1]
y = temp[2]
z = temp[3]
break
for sublist in data:
sublist[1] = sublist[1] - x# assign new elements to original list data
sublist[2] = sublist[2] - y
sublist[3] = sublist[3] - z
line += 10
return data
This is one way to do what you want
from pprint import pprint
def next_mul(n):
"returns next multiple of 10 greater than n"
return n + (10 - n % 10)
# sample data
data = [[i for i in range(4)] for i in range(20)]
for i in range(len(data)):
if i % 10 == 0:
continue
data[i-1][1:] = [k-l for k,l in zip(data[next_mul(i)-1][1:], data[i-1][1:])]
pprint(data)
Output (originally every sublist of data was just [0, 1, 2, 3]):
[[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 1, 2, 3],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 1, 2, 3]]
Hope this helps. Please let me know if there are any questions/concerns!
This is the list that I have:
a = [0, 0, 0, 0, 0, 0, 1, 1, 4, 5, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 3, 4]
I would like to split the list into sublists of 6 zeros in a row and other values to have the desired output of
a = [[0, 0, 0, 0, 0, 0], [1, 1, 4, 5, 0, 0, 4], [0, 0, 0, 0, 0, 0], [1, 3, 4]]
I tried to convert list to string to use split function and then convert string back to list
b = ''.join(map(str,a))
c = b.split('0'*6)
d = list(map(int, c))
and ended up with invalid literal for int() with base 10: '' error message.
Is this the right way to do it? or is there a different way that doesnt involve switching between list and string to avoid such error message?
The following is a quite crude way of doing it:
a = [0, 0, 0, 0, 0, 0, 1, 1, 4, 5, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 3, 4]
output, temp = [], []
while a:
if a[:6] == [0] * 6:
if temp:
output.append(temp)
temp = []
output.append([0] * 6)
a = a[6:]
else:
temp.append(a[0])
a = a[1:]
else:
if temp:
output.append(temp)
print(output)
# [[0, 0, 0, 0, 0, 0], [1, 1, 4, 5, 0, 0, 4], [0, 0, 0, 0, 0, 0], [1, 3, 4]]
This will deplete the original list a.
One way to do this is to make a generator that keeps track of the seen zeros so far and seen numbers so far. When you get six zeros, you yield it and any previous numbers. Otherwise move the zeros to the other list.
a = [0, 0, 0, 0, 0, 0, 1, 1, 4, 5, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 3, 4]
def six_zeros(l):
z = []
nums = []
for n in l:
if n != 0:
nums.extend(z) # add zeros seen so far
nums.append(n) # append the number
z = []
else:
z.append(n) # append the zero
if len(z) == 6: # but you've seen 6 yield them
if nums:
yield nums
yield z
nums = []
z = []
if nums or z: # don't forget any left-overs
nums.extend(z)
yield nums
list(six_zeros(a))
# [[0, 0, 0, 0, 0, 0], [1, 1, 4, 5, 0, 0, 4], [0, 0, 0, 0, 0, 0], [1, 3, 4]]
I think this might be a simpler way:
a = [0, 0, 0, 0, 0, 0, 1, 1, 4, 5, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 3, 4]
six_zeros = [0]*6
b, temp = [], []
for x in a:
temp.append(x)
temp_len = len(temp)
if temp_len >= 6 and temp[-6:] == six_zeros:
if temp_len > 6:
b.append(temp[:-6])
b.append(six_zeros)
temp.clear()
if temp:
b.append(temp)
print(b)
Output:
[[0, 0, 0, 0, 0, 0], [1, 1, 4, 5, 0, 0, 4], [0, 0, 0, 0, 0, 0], [1, 3, 4]]
Here's a working version of your attempt:
import re
a = [0, 0, 0, 0, 0, 0, 1, 1, 4, 5, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 3, 4]
b = ''.join(map(str, a))
c = re.split(f"({'0'*6})", b)
d = [list(map(int, g)) for g in c if g]
print(d)
Output as desired:
[[0, 0, 0, 0, 0, 0], [1, 1, 4, 5, 0, 0, 4], [0, 0, 0, 0, 0, 0], [1, 3, 4]]
I used re.split because that includes the splitters when asked to.
I'm doing exercise questions from A Practical Introduction to Python Programming by Brian Heinold (pg 83) and there was a simpler question:
Using a for loop, create the list below, which consists of ones separated by increasingly many
zeroes. The last two ones in the list should be separated by ten zeroes.
[1,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,....]
# Question 11
L = [1]
for i in range(11):
if i == 0:
L.append(1)
else:
for j in range(i):
L.append(0)
L.append(1)
print(L)
Use a list comprehension to create the list below, which consists of ones separated by increasingly many zeroes. The last two ones in the list should be separated by ten zeroes.
[1,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,....]
I'm having difficulty with converting it into one line using list comprehension. Best I could do was
# Question 15
L = [[1, [0]*i] for i in range(11)]
print(L)
L = [j for row in L for j in row]
print(L)
Which would print:
[[1, []], [1, [0]], [1, [0, 0]], [1, [0, 0, 0]], [1, [0, 0, 0, 0]], [1, [0, 0, 0, 0, 0]], [1, [0, 0, 0, 0, 0, 0]], [1, [0, 0, 0, 0, 0, 0, 0]], [1, [0, 0, 0, 0, 0, 0, 0, 0]], [1, [0, 0, 0, 0, 0, 0, 0, 0, 0]], [1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]]
[1, [], 1, [0], 1, [0, 0], 1, [0, 0, 0], 1, [0, 0, 0, 0], 1, [0, 0, 0, 0, 0], 1, [0, 0, 0, 0, 0, 0], 1, [0, 0, 0, 0, 0, 0, 0], 1, [0, 0, 0, 0, 0, 0, 0, 0], 1, [0, 0, 0, 0, 0, 0, 0, 0, 0], 1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
Flattening the list any further would result in a TypeError: 'int' object is not iterable and I would have to add another 1 at the end of the list using a seperate command which I guess would be fine. To add the code for flattening the list kinda goes over my head.
This is a second attempt using if/else statements, that gives the produces the same output and gives the same TypeError for when I try to flatten it completely.
L = [1 if i%2 == 0 else [0]*(i//2) for i in range(22)]
L = [j for row in L for j in row]
print(L)
I just want this as output:
[1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
Thanks!
You can solve it like this:
L = [j for i in range(11) for j in [1, *([0]*i)]]
or
L = [j for i in range(11) for j in [1, *(0 for k in range(i))]]
Edit
I missed that it should end with a one. Here's a solution that does that:
L = [1, *(j for i in range(11) for j in [*(0 for k in range(i)), 1])]
or with list comprehension instead of generators:
L = [1, *[j for i in range(11) for j in [*[0 for k in range(i)], 1]]]
You could use a nested comprehension that produces an increasing number of values that you convert to 0s and 1s by returning 0s for all but the last of each group:
n = 10
r = [1]+[b//z for z in range(1,n+2) for b in range(1,z+1)]
print(r)
[1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
If you want to avoid the need to add the initial [1], you could use a similar approach starting z at -1 instead of 1:
r = [ 1-(b<z) for z in range(-1,n+1) for b in range(z+1 or 1)]
I know it's not allowed in the problem, but assume we can use math library, there's a really interesting solution that goes like this:
from math import sqrt, floor
print([1] + [1 * ((-1+sqrt(1+8*i))/2 > 0 and floor((-1+sqrt(1+8*i))/2) == (-1+sqrt(1+8*i))/2 or (-1-sqrt(1+8*i))/2 > 0 and floor((-1-sqrt(1+8*i))/2) == (-1-sqrt(1+8*i))/2) for i in range(1, 67)])
The key observation is that all ones in the target list has an index that's a triangular number except for the one on index 0(no pun intended). So we can just check if the current index is a triangular number.
The nth triangular number can be expressed as:
Let i be the current index we are checking. All we need to do is to solve:
And check if one of the roots is a natural number.
Again, I know this is not a valid answer. I just want to show it as the idea is interesting.
p=[]
for i in range(11):
p.append(1)
for j in range(i):
p.append(i*0)
print(p)
I found a question in glassdoor. I do not have additional clarification
Input : an int array [1,0,0,1,1,0,0,1,0,1,0,0,0,1]
you have to come up with a program that will give all possible subsets of the array based on the pattern.
Pattern restrictions were the string array should start with 1 and end with 1. So there will be many sub arrays like from index 0 to 3 and 0 to 4 and index 7 to 9
To solve this I was thinking of using 2 for loops and if both cases the values are equal to 1 then print them.
v=[1,0,0,1,1,0,0,1,0,1,0,0,0,1]
resultList=[]
for i in range(0,len(v)-1):
for j in range(i+1, len(v)):
if v[i]==1 and v[j]==1:
r=v[i:j]
resultList.append(r)
print(resultList)
Output:[[1, 0, 0], [1, 0, 0, 1], [1, 0, 0, 1, 1, 0, 0], [1, 0, 0, 1, 1, 0, 0, 1, 0], [1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0], [1], [1, 1, 0, 0],
I only see 1 correct value so far in output [1, 0, 0, 1]. Should I have used set instead of list? I tried that but that approach did not work either. Can someone kindly give some directions on how to solve this problem?
Thanks for your time.
You can use itertools.combinations to pick 2 indices where the values are non-zeroes in the list:
from itertools import combinations
a = [1,0,0,1,1,0,0,1,0,1,0,0,0,1]
[a[i: j + 1] for i, j in combinations((i for i, n in enumerate(a) if n), 2)]
This returns:
[[1, 0, 0, 1], [1, 0, 0, 1, 1], [1, 0, 0, 1, 1, 0, 0, 1], [1, 0, 0, 1, 1, 0, 0, 1, 0, 1], [1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1], [1, 1], [1, 1, 0, 0, 1], [1, 1, 0, 0, 1, 0, 1], [1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1, 0, 1], [1, 0, 0, 1, 0, 1, 0, 0, 0, 1], [1, 0, 1], [1, 0, 1, 0, 0, 0, 1], [1, 0, 0, 0, 1]]
The probelm is in v[i:j]. Change v[i:j] to v[i:j+1]