num_row = 3
num_col = [2, 4, 8]
# columns, row
list_2d = [[0 for i in range(num_row)] for j in num_col]
#list_2d = [[0 for i in range(num_row)] for j in num_col[:]] # SyntaxError: invalid syntax
#list_2d = [[0 for i in range(num_row)] for num_col[:]] #SyntaxError: invalid syntax
#list_2d = [[0 for i in range(num_row)] for j in num_col[j]] #IndexError: list index out of range
print('\nlist_2d:')
for i in list_2d:
print(i)
print('\nnum_col:')
for j in num_col[:]:
print(j)
My goal is to declare/initialize a list of list where the number of row elements is provided by an array (i.e., the first element of the array gives the number of columns in the first row, the second element of the array gives the number of columns in the second row, etc.). For the life of me, I cannot figure out how to accomplish this.
What I get:
list_2d:
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
num_col:
2
4
8
What I want:
[0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
[[0 for i in range(j)] for j in num_col]
num_row will always be three, you want to use j instead
Another way would be to use *. Here's an example
>>> [0]*10
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Applying the same, you could also do this as follows:
num_col = [2,4,8]
result = [[0]*j for j in num_col]
Related
I see that a simple checkerboard pattern can be created fairly concisely with numpy Does anyone know if a checkerboard where each square may contain multiple values could be created? E.g.:
1 1 0 0 1 1
1 1 0 0 1 1
0 0 1 1 0 0
0 0 1 1 0 0
Although there is no equivalent of np.indices in PyTorch, you can still find a workaround using a combination of torch.arange, torch.meshgrid, and torch.stack:
def indices(h,w):
return torch.stack(torch.meshgrid(torch.arange(h), torch.arange(w)))
This allows you to define a base tensor with a checkboard pattern following your linked post:
>>> base = indices(2,3).sum(axis=0) % 2
tensor([[0, 1, 0],
[1, 0, 1]])
Then you can repeat the row end columns with torch.repeat_interleave:
>>> base.repeat_interleave(2, dim=0).repeat_interleave(2, dim=1)
tensor([[0, 0, 1, 1, 0, 0],
[0, 0, 1, 1, 0, 0],
[1, 1, 0, 0, 1, 1],
[1, 1, 0, 0, 1, 1]])
And you can take the opposite of a given checkboard x by computing 1-x.
So you could define a function like this:
def checkerboard(shape, k):
"""
shape: dimensions of output tensor
k: edge size of square
"""
h, w = shape
base = indices(h//k, w//k).sum(dim=0) % 2
x = base.repeat_interleave(k, 0).repeat_interleave(k, 1)
return 1-x
And try with:
>>> checkerboard((4,6), 2)
tensor([[1, 1, 0, 0, 1, 1],
[1, 1, 0, 0, 1, 1],
[0, 0, 1, 1, 0, 0],
[0, 0, 1, 1, 0, 0]])
I need a generator that yields every bit pattern of n bits in order of their sum (and more). For example for n=3,
1. sum([0, 0, 0]) = 0 ✓
2. sum([1, 0, 0]) = 1 ✓
3. sum([0, 1, 0]) = 1 ✓
4. sum([1, 1, 0]) = 2 ⨯ should be swapped with 5.
5. sum([0, 0, 1]) = 1 ⨯
6. sum([1, 0, 1]) = 2 ✓
7. sum([0, 1, 1]) = 2 ✓
8. sum([1, 1, 1]) = 3 ✓
Note that even though 3 and 5 have the same sum, 5 should be generated after 3. The correct order would have been, 000, 100, 010, 001, 110, 101, 011, 111. The idea here is that if this (2ⁿ, n) dimension matrix was multiplied by a (n, 1) vector that is sorted in ascending order than the product would be sorted as well. Eliminating the need to sort this product will help in optimising an experiment I am trying to run.
Here is my rather inefficient and incomplete attempt,
def forwards(n):
ls = [0]*n
for i in range(n):
for j in range(n-i):
copy = list(ls)
copy[j] = 1
yield copy
ls[-(i+1)] = 1
As you can see, this does get the order right but misses some patterns.
Here is another somewhat efficient but wrong order attempt.
def forwards(n):
for i in range(1 << n):
yield [(i >> k) & 1 for k in range(n)]
This one generates all patterns but in the wrong (shown in the example above) order.
I need this function to be efficient so solutions where a string is generated and then characters are converted to integers are discouraged.
Lastly, I am working in Python 3.9. You can use Numpy.
I believe this gives you the order you want:
First, sort in ascending order by number of 1's
Next, sort in descending order by lexicographical order
from itertools import combinations
def forwards(n):
for one_bits in range(n + 1):
for combination in combinations(range(n), one_bits):
yield [1 if x in combination else 0 for x in range(n)]
for x in forwards(4):
print("{}, one bits = {}, binary value = {}".format(x, sum(x), sum(x[i] * 2**(3 - i) for i in range(4))))
This works by handling the first condition in the first for loop for one_bits in range(n + 1):, and generating all possible N-sized combinations of indices between 0 and n - 1, and then those indices are set to 1, else 0.
This prints
[0, 0, 0, 0], one bits = 0, binary value = 0
[1, 0, 0, 0], one bits = 1, binary value = 8
[0, 1, 0, 0], one bits = 1, binary value = 4
[0, 0, 1, 0], one bits = 1, binary value = 2
[0, 0, 0, 1], one bits = 1, binary value = 1
[1, 1, 0, 0], one bits = 2, binary value = 12
[1, 0, 1, 0], one bits = 2, binary value = 10
[1, 0, 0, 1], one bits = 2, binary value = 9
[0, 1, 1, 0], one bits = 2, binary value = 6
[0, 1, 0, 1], one bits = 2, binary value = 5
[0, 0, 1, 1], one bits = 2, binary value = 3
[1, 1, 1, 0], one bits = 3, binary value = 14
[1, 1, 0, 1], one bits = 3, binary value = 13
[1, 0, 1, 1], one bits = 3, binary value = 11
[0, 1, 1, 1], one bits = 3, binary value = 7
[1, 1, 1, 1], one bits = 4, binary value = 15
Below is my code.
check = [[0] * 4] * 2
check[0][1] = 1
print(check)
check2 = [[0, 0, 0, 0], [0, 0, 0,0]]
check2[0][1] = 1
print(check2)
result:
[[0, 1, 0, 0], [0, 1, 0, 0]]
[[0, 1, 0, 0], [0, 0, 0, 0]]
I expect check and check2 get same result but it is different.
why check[0][1] and check[1][1] are changed?? not only check[0][0]
check is a shallow copy
check = [[0] * 4] * 2 - Creates only one list [0,0,0,0] and rows 1 and 2 refer to this list.
So changing the elements of one row reflects changes in every other row.
To avoid such a scenario you can use a for-loop to create the list like this
check = [[0 for _ in range(4)] for _ in range(2)]
Now, this will be a deep copy and not shallow copy.
check2 is a deep copy.
check2 = [[0, 0, 0, 0], [0, 0, 0,0]] - Creates two separate lists [0,0,0,0]. Row 1 and Row 2 refers to different copies of [0,0,0,0]
So changing the elements of one row will not reflect any changes in the other row.
Please read this SO answer to fully understand the concepts. https://stackoverflow.com/a/37830340
A = [1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0]
B = 9
I want to find out the distances between the index[9] (B) and each of it's closest's 1's. For example, If we look at list A, we see that index 9 is this:
A = [1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0]
^
I would like to figure out the distances between B(index 9) and it's nearest 1's. For example, the nearest 1's in this case would be this:
A = [1, 0, 0, 0, 1, 0, 0, 1, 0, B, 0, 0, 1, 0]
^ ^
So in this case the output would be:
>> [2, 3] ##Since the distance between 1, 0, B is 2 and the distance between B, 0, 0, 1 is 3.
So far I've come up with the following code:
def checkDistance(A, B):
for i in A:
if i == 1:
#Check if it is the closest to B
#Check distance
Sadly I'm a beginner in python and I am struggling to finish. Any help would be much appreciated :)
def distance(lst,index):
c=[i for i,j in enumerate(lst) if j==1]
for k,l in zip(c[:-1],c[1:]):
if k < index < l:
return [index-k, l-index]
a = [1, 0, 0, 0, 1, 0, 0, 1, 0, B, 0, 0, 1, 0]
b = 9
distance(a, b)
Out: [2, 3]
You could use the following function. In this case, to make the function more abstract, you needn't force the value for the comparison to be 1 in the function.
In the function below, you do a for loop starting at the position you specified (in Python indexes start at 0, not at 1) and finishing when the list finishes.
The if statement compares element with the value of the list at a given position i
def checkDistance(lst,index,element):
counter = 0
results = []
for i in range(index,len(lst)):
if lst[i] == element:
print("Detected element at distance: " + str(counter))
results.append(counter)
counter += 1
return results
Hope you can help me with this:
previous=[[0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 1, 2], [0, 0, 1, 2], [0, 0, 1, 1], [0, 1, 1, 2], [0, 1, 1, 1], [0, 0, 1, 2], [0, 1, 1, 2], [0, 0, 0, 0]]
type(previous)
Out[67]: list
previous[0][-1]
Out[66]: 1
previous[1][-1]
Out[65]: 0
for p in previous:
print(p)
[0, 0, 1, 1]
[0, 0, 0, 0]
[0, 0, 1, 2]
[0, 0, 1, 2]
[0, 0, 1, 1]
[0, 1, 1, 2]
[0, 1, 1, 1]
[0, 0, 1, 2]
[0, 1, 1, 2]
[0, 0, 0, 0]
My Question, I need to get the 3 value from each element in the sub list and append it to create another list.
The result should be:
[1,0,1,1,1,1,1,1,1,0]
I tried this but without success:
mylist=[]
for p in previous:
for x in p:
mylist.append(p[x][-1])
print(mylist)
and:
for p in previous:
for x in p:
print ([p[x]])
p is the sublist, you don't need to loop over it again with for x in p: to get the third element (so your code actually raises an IndexError when trying to index the sublist p if x is out of its bound, and will raise an TypeError when trying to use p[x][-1] to index the number at p[x]), still, p[-1] is the last element (the fourth in your case), you should either use positive indexing:
p[2] # the third element
Or use negative indexing to get the next-to-last element:
p[-2]
But if the lists should grow any longer, positive indexing is better since it won't be affected by elements added to the end of the list.
You could also write a list comprehension instead of a for loop + append:
mylist = [p[2] for p in previous]
print(mylist)
Output:
[1, 0, 1, 1, 1, 1, 1, 1, 1, 0]
In your loop p is the sublist. The first time through the loop p is
[0, 0, 1, 1]
Python does zero based indexing (the first element is always at index 0). So p[0] is the first element. The third element would be p[2].
If you use negative indexes, -1 gives the last element and -2 is the next-to-last or penultimate element.
To modify your solution to work, you can remove the inner loop. You don't need it. You already have the sublist.
mylist=[]
for p in previous:
mylist.append(p[2])
print(mylist)