I have a list[5][5] to populate... it looks like a table with 5 columns and 5 rows.
Each cell can be either one or zero.
I want to find different 2^25 possibility that can exist. Each possiblity is a combination of either 0 or 1 in a 5*5 table/list
How can I do that? With nested loop or something?
I suggest you start small... with a 1x1 list first and check that you can display both of the available combinations:
[[0]]
[[1]]
Next up, try a 2x2 list. There are 16 different lists to display:
[[0, 0], [0, 0]]
[[0, 0], [0, 1]]
[[0, 0], [1, 0]]
[[0, 0], [1, 1]]
[[0, 1], [0, 0]]
[[0, 1], [0, 1]]
[[0, 1], [1, 0]]
[[0, 1], [1, 1]]
[[1, 0], [0, 0]]
[[1, 0], [0, 1]]
[[1, 0], [1, 0]]
[[1, 0], [1, 1]]
[[1, 1], [0, 0]]
[[1, 1], [0, 1]]
[[1, 1], [1, 0]]
[[1, 1], [1, 1]]
If you've got the algorithm right for 1x1 and 2x2, then you should be able to generalise it to print your 5x5.
Good luck!
Update
Since you appear to be still struggling, here's a little extra help.
Break this problem into smaller problems. I'd start with generating the values. If you ignore the list notation in my examples above, you'll see that the sequence of values is one that is recognisable to every computer scientist on the planet. It's also pretty easy to generate in Python using bin() and str.zfill().
The second problem is putting them into lists. This isn't too hard either. Supposing the first value in your sequence is '0000'. You know that your lists are two rows by two columns. You can put the first two characters into a list and put that list into a list. Then put the next two characters into a list and append that list to the previous one. Done. Repeat for each value in the sequence.
Hope this helps.
You could try:
import itertools
gen = itertools.product((0,1),repeat=25)
To create a generator to get all of the combinations in 1d and then reshape the data as needed.
Related
I want to find 2D array's index and make it array.
for example:
data_pre=[[1,1,1,0,0,0],[1,0,1,0,0,0],[1,0,0,0,1,0],[1,0,0,0,0,0]]
i wanna find index that have one and wanna make it like this
b=[[0,1,2],[0,2],[0,4],[0]]
Code:
result = []
for i in range(len(data_pre)):
arr=data_pre[i]
currentArrResult=[]
for j in range(len(arr)):
if arr[j]==1:
currentArrResult.append(j)
result.append(currentArrResult)
I tried like that but output is wrong.
[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 2], [0, 2], [0, 4], [0, 4], [0]]
I don't know which part is wrong...
you should not collect output inside the inner loop. that may get a result like this :
[[0],[0, 1],[0, 1, 2],
[0],[0, 2],
[0],[0, 4],
[0]]
you can check that by printing currentArrResult after append finish.
but you got different outcome because of data reference.
you should collect result after inner loop finish its work.
like:
result = []
for i in range(len(data_pre)):
arr=data_pre[i]
currentArrResult=[]
for j in range(len(arr)):
if arr[j]==1:
currentArrResult.append(j)
#print(currentArrResult)
result.append(currentArrResult)
This is probably a very basic question but I dont know what I have to search for to find the answer for it:
I have this code:
list = [[0,1],[0,2],[1,3],[1,4],[1,5]]
list.append(list[0])
for i in list:
i.append(0)
print(list)
This List will later be used as coordinates for a curve. I need to duplicate the first coordinate at the end to get a closed curve.
If I then want to add a third value to each coordinate in the list the first and last item in list will be iterated over twice:
[[0, 1, 0, 0], [0, 2, 0], [1, 3, 0], [1, 4, 0], [1, 5, 0], [0, 1, 0, 0]]
I am guessing they have the same memory address and thereby the append-function is applied to the same object at this address once for the first index and once for the last.
What is this phenomenon called ? what is the easiest way to get the list like this:
[[0, 1, 0], [0, 2, 0], [1, 3, 0], [1, 4, 0], [1, 5, 0], [0, 1, 0]]
Thank you for your help
You can do a list comprehension:
list = [[0,1],[0,2],[1,3],[1,4],[1,5]]
list.append(list[0])
list = [x + [0] for x in list]
print(list)
# [[0, 1, 0], [0, 2, 0], [1, 3, 0], [1, 4, 0], [1, 5, 0], [0, 1, 0]]
EDIT: The trick here is, using x + [0] within the list comprehension. This way new lists are created, thus you do not append 0 to the same list twice (Hattip to #dx_over_dt)
The problem you have with your approach is, that the first and last element of your list refers to the very same object. You can see this, when you print i and list for every iteration:
for i in list:
i.append(0)
print(i)
print(list)
So for the first and last i in your loop, you will append a 0 to the very same list.
You could stick to your approach appending a copy of the first element:
list.append(list[0].copy())
The simplest answer is to add the 0's before appending the closing point.
list = [[0,1],[0,2],[1,3],[1,4],[1,5]]
for i in list:
i.append(0)
list.append(list[0])
print(list)
It's the tiniest bit more efficient than a list comprehension because it's not making copies of the elements.
Let's say we have two nested lists: L1 = [[0, 1], [0, 2]] and L2 = [[1, 2], [1, 3]]
The question is, does there exist a bijection between the integers in one list and the integers in the other list which transforms L1 into L2? For L1 and L2 given above, the answer is yes.
BIJECTION:
old 0 becomes new 1
old 1 becomes new 2
old 2becomes new 3
Recall our nested list L1 = [[0, 1], [0, 2]]. If we apply the mapping described above, then we get L2 = [[1, 2], [1, 3]] Therefore, foo(L1, L2) should return True. foo is the name of the equality operator we are trying to implement.
Also, order does not matter. Each list should be treated as a mathematical "set."
Some examples are shown below:
Left list: [[2, 1], [3, 1]]
Right list: [[1, 2], [1, 3]] : True
foo(left,right) returns True
why?
order doesn't matter
Left list: [[2, 1], [3, 1]]
Right list: [[1, 2], [3, 4]]
foo(left,right) returns False
why?
Two integers inside of the left list are the same, but all integers inside of the right list are different from each-other.
left= [[2, 1], [3, 1]]
right = [[0, 1], [0, 1]]
foo(left, right) returns False
why?
the right list contains only 2 distinct integers (0 and 1). The left list contains 3 distinct integers (1, 2, 3)
Some longer examples are shown below:
Original list: [[0, 1], [0, 2], [1, 2], [1, 3], [0, 1, 2]]
A1: [[4, 1], [4, 0], [1, 0], [1, 3], [4, 1, 0]] : True
A2: [[4, 1], [4, 0], [1, 3], [1, 0], [4, 0, 1]] : True
B: [[1, 2], [3, 1], [2, 4], [1, 4], [2, 4, 1]] : True
C: [[3, 2], [5, 2], [5, 0], [0, 2], [5, 0, 2]] : True
D: [[5, 2], [5, 2], [3, 0], [0, 2], [5, 0, 2]] : False
E: [[3, 0], [0, 3], [5, 0], [0, 2], [5, 0, 2]] : False
Bijection for Example A1:
ORIGINAL A
0 4
1 1
2 0
3 3
A2 is simply a reordering of A1
In example B, 2 and 4 are playing the same role as 0 and 2 in the original list. 1 is in the same role in both lists, as is 3.
In example C, 0 and 5 are playing the same role as 0 and 2 in the original list, 2 is playing the same role as 1 in the original list, and 3 is playing the same role in both lists.
In example D, there are two sub-lists which are the same ([5, 2]), while the original list has no repeating sub-lists.
In example E, 0 is in all four length-2 sub-lists, while in the original list, no number is in all four length-2 sub-lists.
Here is the code I have from my attempt, however it does not work when a low number (like 0) is exchanged for one of the largest numbers in the lists (like say 4). When it does the sorting, it fails to recognize that the 4 is playing the same role as the 0. Since low numbers can be exchanged for high numbers, sorting will not work.
def CheckUnique(configs, newconfig):
sortednewconfig = sorted([sorted(i) for i in newconfig])
presentnumbers = []
canonicalnewconfig = []
for sub in sortednewconfig:
for i in sub:
if i not in presentnumbers:
presentnumbers.append(i)
for sub in sortednewconfig:
cansub = []
for i in sub:
cansub.append(presentnumbers.index(i))
canonicalnewconfig.append(cansub)
if canonicalnewconfig not in configs:
return True
else:
return False
Use a all and any with a zip with it:
>>> l = [[0, 1], [0, 2], [1, 2], [1, 3], [0, 1, 2]]
>>> l2 = [[4, 1], [4, 0], [1, 3], [1, 0], [4, 0, 1]]
>>> all([any(i in x for i in y) for x, y in zip(l, l2)])
True
>>> l3 = [[5, 2], [5, 2], [3, 0], [0, 2], [5, 0, 2]]
>>> all([any(i in x for i in y) for x, y in zip(l, l3)])
False
>>>
You are trying to solve a modified form of what is known as the "graph isomorphism problem." There are existing algorithms which will determine if two graphs are isomorphic, but existing algorithms are all very slow, particularly for large graphs.
"Graphs" are diagrams with dots and lines.
Suppose we have two nested lists:
L1 = [[0, 1], [0, 2], [1, 2], [1, 3], [0, 1, 2]]
L2 = [[4, 1], [4, 0], [1, 3], [1, 0], [4, 0, 1]]
Draw a picture L1 by from the following instructions:
For each element of a sublist, draw a dot. For example consider the sublist
[0, 1]. It will get two dots, one dot for 0 and one dot for 1.
Draw a circle around a cluster of dots if they are in the same
sub-list.
Draw a line between two dots if the two dots represent the same integer.
After that, condense each group of dots (sublist) into a single dot.
You can draw a similar diagram for nested list L2 The question is, after you remove the all of the numbers, do the two diagrams for L1 and L2 look the same? You might have to swap the colors around (blue edges become red, red become, blue, etc...) Also the dots might have to be moved around until it looks the same.
The traditional graph isomorphism problem has the lines connecting dots all of the same color. Your problem is slightly different from traditional in that your edges are colored.
I think that you can get rid of the separate colors and simply number each edge with the number of colors that used to be there. It then becomes an "edge-weighted graph"
Do a google search for "graph isomorphism for edge-weighted graphs."
What you are working on is extremely difficult. I recommend looking at local university math department websites for people you can contact. Looking for email address of professors whose job title is "graph theorist." Contact them, and ask for their advice.
Like I said, what you are working on is extremely difficult.
I think that you can solve it as follows:
Build the edge-weighted graph for the left list
Build the edge-weighted graph for the right list
Determine if the two graphs are isomorphic or not.
I have this list
list = [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 1], [2, 2], [2, 0]]
I want to take 2 integers
row = 2 and column = 1
Combine them
thing = (str(row) + str(", ") + str(column))
then I want to remove the list
[2, 1]
from the array. How would I do this?
EDIT: The language is Python
First of all, don't name your list list. It will overwrite the builtin function list() and potentially mess with your code later.
Secondly, finding and removing elements in a list is done like
data.remove(value)
or in your case
data.remove([2, 1])
Specifically, where you are looking for an entry [row, column], you would do
data.remove([row, column])
where row and column are your two variables.
It may be a bit confusing to name them row and column, though. because your data could be interpreted as a matrix/2D array, where "row" and "column" have a different meaning.
I have constructed a 3 level nested list
#run on Python 3.2.3 32 bit on Win 7
L2=list(0 for i in range(2))
L3=list(L2 for i in range(3))
L4=list(L3 for i in range(4))
#give a new value to the very first number in list:
L4[0][0][0]=5
print("L4:")
print(L4)
#outputs erronously:
#[[[5, 0], [5, 0], [5, 0]], [[5, 0], [5, 0], [5, 0]], [[5, 0], [5, 0], [5, 0]], [[5, 0], [5, 0], [5, 0]]]
The same list given explicitly
#the same L4 given explicitly:
anotherL4=[[[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
print("anotherL4:")
#give a new value to the very first number:
anotherL4[0][0][0]=5
print(anotherL4)
#outputs correctly:
#[[[5, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
You're wrong. You've copied the reference multiple times, which means they're actually all the same list.
When you write list(L3 for i in range(4)), you are telling it to yield the same list L3 on each iteration of the generator comprehension. When you subsequently modify that list, the modifications show up everywhere, because all of them are references to the same list.
You could get the effect you seem to want by doing
list(list(L3) for i in range(4))
since using list(L3) makes a new list.
Just to elaborate,
a = 1
b = 2
c = [a,b]
a += 1
print c
Your problem is that you built a list of list references rather than a list of lists. Since the references all pointed back to a single list, when you mutate that single list, all the references show the change.
L0 = range(3)
L1 = range(3)
print(id(L0)) # prints a number
print(id(L1)) # prints a different number
print(id(L0) == id(L1)) # prints False
print(L0 is L1) # prints False; not same objects
print(L0 == L1) # prints True; values match
# your original code:
L2=list(0 for i in range(2))
L3=list(L2 for i in range(3))
L4=list(L3 for i in range(4))
print(L3[0] is L2) # prints True; L3[0] is a reference to L2
We can fix it and explicitly show what we are doing by using copy.deepcopy():
import copy
L2 = [0 for i in range(2)]
L3 = [copy.deepcopy(L2) for i in range(3)]
L4 = [copy.deepcopy(L3) for i in range(4)]
#give a new value to the very first number in list:
L4[0][0][0]=5
print("L4:")
print(L4)
Note that instead of making a generator expression and passing it to list() to force it to be expanded out to a list, I just used list comprehensions in the above code to directly make lists.
More usually if you want to do this crazy thing, you should maybe just nest some list comprehensions:
L4 = [[[0 for _ in range(2)] for _ in range(3)] for _ in range(4)]
This makes it pretty clear that we are building a new list of lists of lists. And if you use copy.deepcopy() you are basically just copying a bunch of zeroes, so you might as well just build new lists using zeroes.